[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/ -> class-wp-list-util.php (source)

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


Generated: Tue Oct 22 08:20:01 2019 Cross-referenced by PHPXref 0.7