<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[38859] trunk: General: Introduce a `wp_list_sort()` helper function.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/38859">38859</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/38859","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>swissspidy</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-10-21 11:11:42 +0000 (Fri, 21 Oct 2016)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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 <a href="https://core.trac.wordpress.org/ticket/37128">#37128</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludescategorytemplatephp">trunk/src/wp-includes/category-template.php</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizemanagerphp">trunk/src/wp-includes/class-wp-customize-manager.php</a></li>
<li><a href="#trunksrcwpincludescustomizeclasswpcustomizenavmenuitemsettingphp">trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php</a></li>
<li><a href="#trunksrcwpincludescustomizeclasswpcustomizenavmenusettingphp">trunk/src/wp-includes/customize/class-wp-customize-nav-menu-setting.php</a></li>
<li><a href="#trunksrcwpincludesdeprecatedphp">trunk/src/wp-includes/deprecated.php</a></li>
<li><a href="#trunksrcwpincludesfunctionsphp">trunk/src/wp-includes/functions.php</a></li>
<li><a href="#trunksrcwpincludeslinktemplatephp">trunk/src/wp-includes/link-template.php</a></li>
<li><a href="#trunksrcwpincludesnavmenuphp">trunk/src/wp-includes/nav-menu.php</a></li>
<li><a href="#trunksrcwpsettingsphp">trunk/src/wp-settings.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswplistutilphp">trunk/src/wp-includes/class-wp-list-util.php</a></li>
<li><a href="#trunktestsphpunittestsfunctionswpListUtilphp">trunk/tests/phpunit/tests/functions/wpListUtil.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludescategorytemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/category-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/category-template.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/category-template.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -100,45 +100,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Sort categories by name.
- *
- * Used by usort() as a callback, should not be used directly. Can actually be
- * used to sort any term object.
- *
- * @since 2.3.0
- * @access private
- *
- * @param object $a
- * @param object $b
- * @return int
- */
-function _usort_terms_by_name( $a, $b ) {
- return strcmp( $a->name, $b->name );
-}
-
-/**
- * Sort categories by ID.
- *
- * Used by usort() as a callback, should not be used directly. Can actually be
- * used to sort any term object.
- *
- * @since 2.3.0
- * @access private
- *
- * @param object $a
- * @param object $b
- * @return int
- */
-function _usort_terms_by_ID( $a, $b ) {
- if ( $a->term_id > $b->term_id )
- return 1;
- elseif ( $a->term_id < $b->term_id )
- return -1;
- else
- return 0;
-}
-
-/**
</del><span class="cx" style="display: block; padding: 0 10px"> * Retrieve category name based on category ID.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 0.71
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpcustomizemanagerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-customize-manager.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-customize-manager.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/class-wp-customize-manager.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2505,12 +2505,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Helper function to compare two objects by priority, ensuring sort stability via instance_number.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.4.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @deprecated 4.7.0 Use wp_list_sort()
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control $a Object A.
</span><span class="cx" style="display: block; padding: 0 10px"> * @param WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control $b Object B.
</span><span class="cx" style="display: block; padding: 0 10px"> * @return int
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function _cmp_priority( $a, $b ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( $a->priority === $b->priority ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return $a->instance_number - $b->instance_number;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2530,7 +2533,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function prepare_controls() {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $controls = array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- uasort( $this->controls, array( $this, '_cmp_priority' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->controls = wp_list_sort( $this->controls, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $this->controls as $id => $control ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2543,7 +2549,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->controls = $controls;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Prepare sections.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- uasort( $this->sections, array( $this, '_cmp_priority' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->sections = wp_list_sort( $this->sections, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> $sections = array();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $this->sections as $section ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2551,8 +2560,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- usort( $section->controls, array( $this, '_cmp_priority' ) );
</del><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $section->controls = wp_list_sort( $section->controls, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! $section->panel ) {
</span><span class="cx" style="display: block; padding: 0 10px"> // Top-level section.
</span><span class="cx" style="display: block; padding: 0 10px"> $sections[ $section->id ] = $section;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2566,7 +2579,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->sections = $sections;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Prepare panels.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- uasort( $this->panels, array( $this, '_cmp_priority' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->panels = wp_list_sort( $this->panels, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> $panels = array();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $this->panels as $panel ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2574,14 +2590,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- uasort( $panel->sections, array( $this, '_cmp_priority' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $panel->sections = wp_list_sort( $panel->sections, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> $panels[ $panel->id ] = $panel;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->panels = $panels;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Sort panels and top-level sections together.
</span><span class="cx" style="display: block; padding: 0 10px"> $this->containers = array_merge( $this->panels, $this->sections );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- uasort( $this->containers, array( $this, '_cmp_priority' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->containers = wp_list_sort( $this->containers, array(
+ 'priority' => 'ASC',
+ 'instance_number' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunksrcwpincludesclasswplistutilphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/class-wp-list-util.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-list-util.php (rev 0)
+++ trunk/src/wp-includes/class-wp-list-util.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,260 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * WordPress List utility class
+ *
+ * @package WordPress
+ * @since 4.7.0
+ */
+
+/**
+ * List utility.
+ *
+ * Utility class to handle operations on an array of objects.
+ *
+ * @since 4.7.0
+ */
+class WP_List_Util {
+ /**
+ * The input array.
+ *
+ * @since 4.7.0
+ * @access private
+ * @var array
+ */
+ private $input = array();
+
+ /**
+ * The output array.
+ *
+ * @since 4.7.0
+ * @access private
+ * @var array
+ */
+ private $output = array();
+
+ /**
+ * Temporary arguments for sorting.
+ *
+ * @since 4.7.0
+ * @access private
+ * @var array
+ */
+ private $orderby = array();
+
+ /**
+ * Constructor.
+ *
+ * Sets the input array.
+ *
+ * @since 4.7.0
+ *
+ * @param array $input Array to perform operations on.
+ */
+ public function __construct( $input ) {
+ $this->output = $this->input = $input;
+ }
+
+ /**
+ * Returns the original input array.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return array The input array.
+ */
+ public function get_input() {
+ return $this->input;
+ }
+
+ /**
+ * Returns the output array.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return array The output array.
+ */
+ public function get_output() {
+ return $this->output;
+ }
+
+ /**
+ * Filters the list, based on a set of key => value arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param array $args Optional. An array of key => value arguments to match
+ * against each object. Default empty array.
+ * @param string $operator Optional. The logical operation to perform. 'AND' means
+ * all elements from the array must match. 'OR' means only
+ * one element needs to match. 'NOT' means no elements may
+ * match. Default 'AND'.
+ * @return array Array of found values.
+ */
+ public function filter( $args = array(), $operator = 'AND' ) {
+ if ( empty( $args ) ) {
+ return $this->output;
+ }
+
+ $operator = strtoupper( $operator );
+
+ if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) {
+ return array();
+ }
+
+ $count = count( $args );
+ $filtered = array();
+
+ foreach ( $this->output as $key => $obj ) {
+ $to_match = (array) $obj;
+
+ $matched = 0;
+ foreach ( $args as $m_key => $m_value ) {
+ if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) {
+ $matched++;
+ }
+ }
+
+ if ( ( 'AND' == $operator && $matched == $count )
+ || ( 'OR' == $operator && $matched > 0 )
+ || ( 'NOT' == $operator && 0 == $matched ) ) {
+ $filtered[$key] = $obj;
+ }
+ }
+
+ $this->output = $filtered;
+
+ return $this->output;
+ }
+
+ /**
+ * Plucks a certain field out of each object in the list.
+ *
+ * This has the same functionality and prototype of
+ * array_column() (PHP 5.5) but also supports objects.
+ *
+ * @since 4.7.0
+ *
+ * @param int|string $field Field from the object to place instead of the entire object
+ * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
+ * Default null.
+ * @return array Array of found values. If `$index_key` is set, an array of found values with keys
+ * corresponding to `$index_key`. If `$index_key` is null, array keys from the original
+ * `$list` will be preserved in the results.
+ */
+ public function pluck( $field, $index_key = null ) {
+ if ( ! $index_key ) {
+ /*
+ * This is simple. Could at some point wrap array_column()
+ * if we knew we had an array of arrays.
+ */
+ foreach ( $this->output as $key => $value ) {
+ if ( is_object( $value ) ) {
+ $this->output[ $key ] = $value->$field;
+ } else {
+ $this->output[ $key ] = $value[ $field ];
+ }
+ }
+ return $this->output;
+ }
+
+ /*
+ * When index_key is not set for a particular item, push the value
+ * to the end of the stack. This is how array_column() behaves.
+ */
+ $newlist = array();
+ foreach ( $this->output as $value ) {
+ if ( is_object( $value ) ) {
+ if ( isset( $value->$index_key ) ) {
+ $newlist[ $value->$index_key ] = $value->$field;
+ } else {
+ $newlist[] = $value->$field;
+ }
+ } else {
+ if ( isset( $value[ $index_key ] ) ) {
+ $newlist[ $value[ $index_key ] ] = $value[ $field ];
+ } else {
+ $newlist[] = $value[ $field ];
+ }
+ }
+ }
+
+ $this->output = $newlist;
+
+ return $this->output;
+ }
+
+ /**
+ * Sorts the list, based on one or more orderby arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param string|array $orderby Optional. Either the field name to order by or an array
+ * of multiple orderby fields as $orderby => $order.
+ * @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
+ * is a string.
+ * @return array The sorted array.
+ */
+ public function sort( $orderby = array(), $order = 'ASC' ) {
+ if ( empty( $orderby ) ) {
+ return $this->output;
+ }
+
+ if ( is_string( $orderby ) ) {
+ $orderby = array( $orderby => $order );
+ }
+
+ foreach ( $orderby as $field => $direction ) {
+ $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC';
+ }
+
+ $this->orderby = $orderby;
+
+ usort( $this->output, array( $this, 'sort_callback' ) );
+
+ $this->orderby = array();
+
+ return $this->output;
+ }
+
+ /**
+ * Callback to sort the list by specific fields.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @see WP_List_Util::sort()
+ *
+ * @param object|array $a One object to compare.
+ * @param object|array $b The other object to compare.
+ * @return int 0 if both objects equal. -1 if second object should come first, 1 otherwise.
+ */
+ private function sort_callback( $a, $b ) {
+ if ( empty( $this->orderby ) ) {
+ return 0;
+ }
+
+ $a = (array) $a;
+ $b = (array) $b;
+
+ foreach ( $this->orderby as $field => $direction ) {
+ if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) {
+ continue;
+ }
+
+ if ( $a[ $field ] == $b[ $field ] ) {
+ continue;
+ }
+
+ $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 );
+
+ if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) {
+ return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1];
+ }
+
+ return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1];
+ }
+
+ return 0;
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludescustomizeclasswpcustomizenavmenuitemsettingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -532,8 +532,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ARRAY_A === $args['output'] ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
- usort( $items, '_sort_nav_menu_items' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $items = wp_list_sort( $items, array(
+ $args['output_key'] => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> $i = 1;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $items as $k => $item ) {
</span></span></pre></div>
<a id="trunksrcwpincludescustomizeclasswpcustomizenavmenusettingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/customize/class-wp-customize-nav-menu-setting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/customize/class-wp-customize-nav-menu-setting.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/customize/class-wp-customize-nav-menu-setting.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -287,8 +287,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Make sure the menu objects get re-sorted after an update/insert.
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! $is_delete && ! empty( $args['orderby'] ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->_current_menus_sort_orderby = $args['orderby'];
- usort( $menus, array( $this, '_sort_menus_by_orderby' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $menus = wp_list_sort( $menus, array(
+ $args['orderby'] => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> // @todo add support for $args['hide_empty'] === true
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -313,7 +314,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * This is a workaround for a lack of closures.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.3.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @deprecated 4.7.0 Use wp_list_sort()
</ins><span class="cx" style="display: block; padding: 0 10px"> * @access protected
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param object $menu1
</span><span class="cx" style="display: block; padding: 0 10px"> * @param object $menu2
</span><span class="cx" style="display: block; padding: 0 10px"> * @return int
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -321,6 +324,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus()
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function _sort_menus_by_orderby( $menu1, $menu2 ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> $key = $this->_current_menus_sort_orderby;
</span><span class="cx" style="display: block; padding: 0 10px"> return strcmp( $menu1->$key, $menu2->$key );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesdeprecatedphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/deprecated.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/deprecated.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/deprecated.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3798,3 +3798,83 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return preg_replace( '%&\s*\{[^}]*(\}\s*;?|$)%', '', $string );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Sort categories by ID.
+ *
+ * Used by usort() as a callback, should not be used directly. Can actually be
+ * used to sort any term object.
+ *
+ * @since 2.3.0
+ * @deprecated 4.7.0 Use wp_list_sort()
+ * @access private
+ *
+ * @param object $a
+ * @param object $b
+ * @return int
+ */
+function _usort_terms_by_ID( $a, $b ) {
+ _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
+
+ if ( $a->term_id > $b->term_id )
+ return 1;
+ elseif ( $a->term_id < $b->term_id )
+ return -1;
+ else
+ return 0;
+}
+
+/**
+ * Sort categories by name.
+ *
+ * Used by usort() as a callback, should not be used directly. Can actually be
+ * used to sort any term object.
+ *
+ * @since 2.3.0
+ * @deprecated 4.7.0 Use wp_list_sort()
+ * @access private
+ *
+ * @param object $a
+ * @param object $b
+ * @return int
+ */
+function _usort_terms_by_name( $a, $b ) {
+ _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
+
+ return strcmp( $a->name, $b->name );
+}
+
+/**
+ * Sort menu items by the desired key.
+ *
+ * @since 3.0.0
+ * @deprecated 4.7.0 Use wp_list_sort()
+ * @access private
+ *
+ * @global string $_menu_item_sort_prop
+ *
+ * @param object $a The first object to compare
+ * @param object $b The second object to compare
+ * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
+ */
+function _sort_nav_menu_items( $a, $b ) {
+ global $_menu_item_sort_prop;
+
+ _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
+
+ if ( empty( $_menu_item_sort_prop ) )
+ return 0;
+
+ if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
+ return 0;
+
+ $_a = (int) $a->$_menu_item_sort_prop;
+ $_b = (int) $b->$_menu_item_sort_prop;
+
+ if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
+ return 0;
+ elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
+ return $_a < $_b ? -1 : 1;
+ else
+ return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/functions.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/functions.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3489,6 +3489,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Filters a list of objects, based on a set of key => value arguments.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 4.7.0 Uses WP_List_Util class.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $list An array of objects to filter
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $args Optional. An array of key => value arguments to match
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3502,21 +3503,26 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @return array A list of objects or object fields.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! is_array( $list ) )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! is_array( $list ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return array();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $list = wp_list_filter( $list, $args, $operator );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $util = new WP_List_Util( $list );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( $field )
- $list = wp_list_pluck( $list, $field );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $util->filter( $args, $operator );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $list;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( $field ) {
+ $util->pluck( $field );
+ }
+
+ return $util->get_output();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Filters a list of objects, based on a set of key => value arguments.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.1.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 4.7.0 Uses WP_List_Util class.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $list An array of objects to filter.
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $args Optional. An array of key => value arguments to match
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3528,33 +3534,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @return array Array of found values.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! is_array( $list ) )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! is_array( $list ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- if ( empty( $args ) )
- return $list;
-
- $operator = strtoupper( $operator );
- $count = count( $args );
- $filtered = array();
-
- foreach ( $list as $key => $obj ) {
- $to_match = (array) $obj;
-
- $matched = 0;
- foreach ( $args as $m_key => $m_value ) {
- if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
- $matched++;
- }
-
- if ( ( 'AND' == $operator && $matched == $count )
- || ( 'OR' == $operator && $matched > 0 )
- || ( 'NOT' == $operator && 0 == $matched ) ) {
- $filtered[$key] = $obj;
- }
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $filtered;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $util = new WP_List_Util( $list );
+ return $util->filter( $args, $operator );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3565,6 +3550,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.1.0
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.0.0 $index_key parameter added.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 4.7.0 Uses WP_List_Util class.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $list List of objects or arrays
</span><span class="cx" style="display: block; padding: 0 10px"> * @param int|string $field Field from the object to place instead of the entire object
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3575,43 +3561,29 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * `$list` will be preserved in the results.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_list_pluck( $list, $field, $index_key = null ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! $index_key ) {
- /*
- * This is simple. Could at some point wrap array_column()
- * if we knew we had an array of arrays.
- */
- foreach ( $list as $key => $value ) {
- if ( is_object( $value ) ) {
- $list[ $key ] = $value->$field;
- } else {
- $list[ $key ] = $value[ $field ];
- }
- }
- return $list;
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $util = new WP_List_Util( $list );
+ return $util->pluck( $field, $index_key );
+}
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- /*
- * When index_key is not set for a particular item, push the value
- * to the end of the stack. This is how array_column() behaves.
- */
- $newlist = array();
- foreach ( $list as $value ) {
- if ( is_object( $value ) ) {
- if ( isset( $value->$index_key ) ) {
- $newlist[ $value->$index_key ] = $value->$field;
- } else {
- $newlist[] = $value->$field;
- }
- } else {
- if ( isset( $value[ $index_key ] ) ) {
- $newlist[ $value[ $index_key ] ] = $value[ $field ];
- } else {
- $newlist[] = $value[ $field ];
- }
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Sorts a list of objects, based on one or more orderby arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param array $list An array of objects to filter.
+ * @param string|array $orderby Optional. Either the field name to order by or an array
+ * of multiple orderby fields as $orderby => $order.
+ * @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
+ * is a string.
+ * @return array The sorted array.
+ */
+function wp_list_sort( $list, $orderby = array(), $order = 'ASC' ) {
+ if ( ! is_array( $list ) ) {
+ return array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $newlist;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $util = new WP_List_Util( $list );
+ return $util->sort( $orderby, $order );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunksrcwpincludeslinktemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/link-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/link-template.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/link-template.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -169,7 +169,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( strpos($permalink, '%category%') !== false ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $cats = get_the_category($post->ID);
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $cats ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- usort($cats, '_usort_terms_by_ID'); // order by ID
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cats = wp_list_sort( $cats, array(
+ 'term_id' => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Filters the category that gets used in the %category% permalink token.
</span></span></pre></div>
<a id="trunksrcwpincludesnavmenuphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/nav-menu.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/nav-menu.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-includes/nav-menu.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -558,38 +558,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Sort menu items by the desired key.
- *
- * @since 3.0.0
- * @access private
- *
- * @global string $_menu_item_sort_prop
- *
- * @param object $a The first object to compare
- * @param object $b The second object to compare
- * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
- */
-function _sort_nav_menu_items( $a, $b ) {
- global $_menu_item_sort_prop;
-
- if ( empty( $_menu_item_sort_prop ) )
- return 0;
-
- if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
- return 0;
-
- $_a = (int) $a->$_menu_item_sort_prop;
- $_b = (int) $b->$_menu_item_sort_prop;
-
- if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
- return 0;
- elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
- return $_a < $_b ? -1 : 1;
- else
- return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
-}
-
-/**
</del><span class="cx" style="display: block; padding: 0 10px"> * Return if a menu item is valid.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @link https://core.trac.wordpress.org/ticket/13958
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -682,8 +650,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ARRAY_A == $args['output'] ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
- usort($items, '_sort_nav_menu_items');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $items = wp_list_sort( $items, array(
+ $args['output_key'] => 'ASC',
+ ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> $i = 1;
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $items as $k => $item ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $items[$k]->{$args['output_key']} = $i++;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -776,7 +745,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $menu_item->type_label = __( 'Post Type Archive' );
</span><span class="cx" style="display: block; padding: 0 10px"> $post_content = wp_trim_words( $menu_item->post_content, 200 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $post_type_description = '' == $post_content ? $post_type_description : $post_content;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $post_type_description = '' == $post_content ? $post_type_description : $post_content;
</ins><span class="cx" style="display: block; padding: 0 10px"> $menu_item->url = get_post_type_archive_link( $menu_item->object );
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ( 'taxonomy' == $menu_item->type ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $object = get_taxonomy( $menu_item->object );
</span></span></pre></div>
<a id="trunksrcwpsettingsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-settings.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-settings.php 2016-10-21 11:02:37 UTC (rev 38858)
+++ trunk/src/wp-settings.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -91,6 +91,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Load early WordPress files.
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/compat.php' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+require( ABSPATH . WPINC . '/class-wp-list-util.php' );
</ins><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/functions.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/class-wp-matchesmapregex.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> require( ABSPATH . WPINC . '/class-wp.php' );
</span></span></pre></div>
<a id="trunktestsphpunittestsfunctionswpListUtilphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/functions/wpListUtil.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/functions/wpListUtil.php (rev 0)
+++ trunk/tests/phpunit/tests/functions/wpListUtil.php 2016-10-21 11:11:42 UTC (rev 38859)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,341 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group functions.php
+ */
+class Tests_WP_List_Util extends WP_UnitTestCase {
+ public function data_test_wp_list_pluck() {
+ return array(
+ 'arrays' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
+ array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum' ),
+ array( 'foo' => 'baz' ),
+ ),
+ 'foo',
+ null,
+ array( 'bar', 'foo', 'baz' ),
+ ),
+ 'arrays with index key' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'key',
+ array( 'foo' => 'bar', 'bar' => 'foo', 'value' => 'baz' ),
+ ),
+ 'arrays with index key missing' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
+ array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'key',
+ array( 'bar' => 'foo', 'value' => 'baz', 'bar' ),
+ ),
+ 'objects' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum' ),
+ (object) array( 'foo' => 'baz' ),
+ ),
+ 'foo',
+ null,
+ array( 'bar', 'foo', 'baz' ),
+ ),
+ 'objects with index key' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'key',
+ array( 'foo' => 'bar', 'bar' => 'foo', 'value' => 'baz' ),
+ ),
+ 'objects with index key missing' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'key',
+ array( 'bar' => 'foo', 'value' => 'baz', 'bar' ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_test_wp_list_pluck
+ *
+ * @param array $list List of objects or arrays.
+ * @param int|string $field Field from the object to place instead of the entire object
+ * @param int|string $index_key Field from the object to use as keys for the new array.
+ * @param array $expected Expected result.
+ */
+ public function test_wp_list_pluck( $list, $field, $index_key, $expected ) {
+ $this->assertEqualSetsWithIndex( $expected, wp_list_pluck( $list, $field, $index_key ) );
+ }
+
+ public function data_test_wp_list_filter() {
+ return array(
+ 'string instead of array' => array(
+ 'foo',
+ array(),
+ 'AND',
+ array(),
+ ),
+ 'object instead of array' => array(
+ (object) array( 'foo' ),
+ array(),
+ 'AND',
+ array(),
+ ),
+ 'empty args' => array(
+ array( 'foo', 'bar' ),
+ array(),
+ 'AND',
+ array( 'foo', 'bar' ),
+ ),
+ 'invalid operator' => array(
+ array(
+ (object) array( 'foo' => 'bar' ),
+ (object) array( 'foo' => 'baz' ),
+ ),
+ array( 'foo' => 'bar' ),
+ 'XOR',
+ array(),
+ ),
+ 'single argument to match' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value' ),
+ (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'foo' => 'bar' ),
+ 'AND',
+ array(
+ 0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ 3 => (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ ),
+ 'all must match' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
+ (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'foo' => 'bar', 'bar' => 'baz' ),
+ 'AND',
+ array(
+ 0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ ),
+ ),
+ 'any must match' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
+ (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'key' => 'value', 'bar' => 'baz' ),
+ 'OR',
+ array(
+ 0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ 2 => (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
+ 3 => (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ ),
+ 'none must match' => array(
+ array(
+ (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
+ (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ (object) array( 'foo' => 'baz', 'key' => 'value' ),
+ (object) array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'key' => 'value', 'bar' => 'baz' ),
+ 'NOT',
+ array(
+ 1 => (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_test_wp_list_filter
+ *
+ * @param array $list An array of objects to filter.
+ * @param array $args An array of key => value arguments to match
+ * against each object.
+ * @param string $operator The logical operation to perform.
+ * @param array $expected Expected result.
+ */
+ public function test_wp_list_filter( $list, $args, $operator, $expected ) {
+ $this->assertEqualSetsWithIndex( $expected, wp_list_filter( $list, $args, $operator ) );
+ }
+
+ public function data_test_wp_list_sort() {
+ return array(
+ 'single orderby ascending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'ASC',
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ ),
+ ),
+ 'single orderby descending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ 'foo',
+ 'DESC',
+ array(
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ ),
+ 'single orderby array ascending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'foo' => 'ASC' ),
+ 'IGNORED',
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ ),
+ ),
+ 'single orderby array descending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'foo' => 'DESC' ),
+ 'IGNORED',
+ array(
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'baz', 'key' => 'value' ),
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ ),
+ 'multiple orderby ascending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'key' => 'ASC', 'foo' => 'ASC' ),
+ 'IGNORED',
+ array(
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ ),
+ 'multiple orderby descending' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'key' => 'DESC', 'foo' => 'DESC' ),
+ 'IGNORED',
+ array(
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ ),
+ ),
+ 'multiple orderby mixed' => array(
+ array(
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ ),
+ array( 'key' => 'DESC', 'foo' => 'ASC' ),
+ 'IGNORED',
+ array(
+ array( 'foo' => 'bar', 'key' => 'value' ),
+ array( 'foo' => 'baz', 'key' => 'key' ),
+ array( 'foo' => 'foo', 'key' => 'key' ),
+ array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
+ array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_test_wp_list_sort
+ *
+ * @param string|array $orderby Either the field name to order by or an array
+ * of multiple orderby fields as $orderby => $order.
+ * @param string $order Either 'ASC' or 'DESC'.
+ */
+ public function test_wp_list_sort( $list, $orderby, $order, $expected ) {
+ $this->assertEquals( $expected, wp_list_sort( $list, $orderby, $order ) );
+ }
+
+ public function test_wp_list_util_get_input() {
+ $input = array( 'foo', 'bar' );
+ $util = new WP_List_Util( $input );
+
+ $this->assertEqualSets( $input, $util->get_input() );
+ }
+
+ public function test_wp_list_util_get_output_immediately() {
+ $input = array( 'foo', 'bar' );
+ $util = new WP_List_Util( $input );
+
+ $this->assertEqualSets( $input, $util->get_output() );
+ }
+
+ public function test_wp_list_util_get_output() {
+ $expected = array( (object) array( 'foo' => 'bar', 'bar' => 'baz' ) );
+
+ $util = new WP_List_Util( array( (object) array( 'foo' => 'bar', 'bar' => 'baz' ), (object) array( 'bar' => 'baz' ) ) );
+ $actual = $util->filter( array( 'foo' => 'bar' ) );
+
+ $this->assertEqualSets( $expected, $actual );
+ $this->assertEqualSets( $expected, $util->get_output() );
+ }
+}
</ins></span></pre>
</div>
</div>
</body>
</html>