[ Index ]

PHP Cross Reference of WordPress

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              $matched = 0;
 106  
 107              foreach ( $args as $m_key => $m_value ) {
 108                  if ( is_array( $obj ) ) {
 109                      // Treat object as an array.
 110                      if ( array_key_exists( $m_key, $obj ) && ( $m_value == $obj[ $m_key ] ) ) {
 111                          $matched++;
 112                      }
 113                  } elseif ( is_object( $obj ) ) {
 114                      // Treat object as an object.
 115                      if ( isset( $obj->{$m_key} ) && ( $m_value == $obj->{$m_key} ) ) {
 116                          $matched++;
 117                      }
 118                  }
 119              }
 120  
 121              if ( ( 'AND' === $operator && $matched === $count )
 122                  || ( 'OR' === $operator && $matched > 0 )
 123                  || ( 'NOT' === $operator && 0 === $matched )
 124              ) {
 125                  $filtered[ $key ] = $obj;
 126              }
 127          }
 128  
 129          $this->output = $filtered;
 130  
 131          return $this->output;
 132      }
 133  
 134      /**
 135       * Plucks a certain field out of each object in the list.
 136       *
 137       * This has the same functionality and prototype of
 138       * array_column() (PHP 5.5) but also supports objects.
 139       *
 140       * @since 4.7.0
 141       *
 142       * @param int|string $field     Field from the object to place instead of the entire object
 143       * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
 144       *                              Default null.
 145       * @return array Array of found values. If `$index_key` is set, an array of found values with keys
 146       *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
 147       *               `$list` will be preserved in the results.
 148       */
 149  	public function pluck( $field, $index_key = null ) {
 150          $newlist = array();
 151  
 152          if ( ! $index_key ) {
 153              /*
 154               * This is simple. Could at some point wrap array_column()
 155               * if we knew we had an array of arrays.
 156               */
 157              foreach ( $this->output as $key => $value ) {
 158                  if ( is_object( $value ) ) {
 159                      $newlist[ $key ] = $value->$field;
 160                  } else {
 161                      $newlist[ $key ] = $value[ $field ];
 162                  }
 163              }
 164  
 165              $this->output = $newlist;
 166  
 167              return $this->output;
 168          }
 169  
 170          /*
 171           * When index_key is not set for a particular item, push the value
 172           * to the end of the stack. This is how array_column() behaves.
 173           */
 174          foreach ( $this->output as $value ) {
 175              if ( is_object( $value ) ) {
 176                  if ( isset( $value->$index_key ) ) {
 177                      $newlist[ $value->$index_key ] = $value->$field;
 178                  } else {
 179                      $newlist[] = $value->$field;
 180                  }
 181              } else {
 182                  if ( isset( $value[ $index_key ] ) ) {
 183                      $newlist[ $value[ $index_key ] ] = $value[ $field ];
 184                  } else {
 185                      $newlist[] = $value[ $field ];
 186                  }
 187              }
 188          }
 189  
 190          $this->output = $newlist;
 191  
 192          return $this->output;
 193      }
 194  
 195      /**
 196       * Sorts the list, based on one or more orderby arguments.
 197       *
 198       * @since 4.7.0
 199       *
 200       * @param string|array $orderby       Optional. Either the field name to order by or an array
 201       *                                    of multiple orderby fields as $orderby => $order.
 202       * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
 203       *                                    is a string.
 204       * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
 205       * @return array The sorted array.
 206       */
 207  	public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
 208          if ( empty( $orderby ) ) {
 209              return $this->output;
 210          }
 211  
 212          if ( is_string( $orderby ) ) {
 213              $orderby = array( $orderby => $order );
 214          }
 215  
 216          foreach ( $orderby as $field => $direction ) {
 217              $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC';
 218          }
 219  
 220          $this->orderby = $orderby;
 221  
 222          if ( $preserve_keys ) {
 223              uasort( $this->output, array( $this, 'sort_callback' ) );
 224          } else {
 225              usort( $this->output, array( $this, 'sort_callback' ) );
 226          }
 227  
 228          $this->orderby = array();
 229  
 230          return $this->output;
 231      }
 232  
 233      /**
 234       * Callback to sort the list by specific fields.
 235       *
 236       * @since 4.7.0
 237       *
 238       * @see WP_List_Util::sort()
 239       *
 240       * @param object|array $a One object to compare.
 241       * @param object|array $b The other object to compare.
 242       * @return int 0 if both objects equal. -1 if second object should come first, 1 otherwise.
 243       */
 244  	private function sort_callback( $a, $b ) {
 245          if ( empty( $this->orderby ) ) {
 246              return 0;
 247          }
 248  
 249          $a = (array) $a;
 250          $b = (array) $b;
 251  
 252          foreach ( $this->orderby as $field => $direction ) {
 253              if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) {
 254                  continue;
 255              }
 256  
 257              if ( $a[ $field ] == $b[ $field ] ) {
 258                  continue;
 259              }
 260  
 261              $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 );
 262  
 263              if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) {
 264                  return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1];
 265              }
 266  
 267              return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1];
 268          }
 269  
 270          return 0;
 271      }
 272  }


Generated: Wed Nov 25 01:00:04 2020 Cross-referenced by PHPXref 0.7.1