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