wp/wp-includes/class-wp-network-query.php
changeset 7 cf61fcea0001
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
       
     1 <?php
       
     2 /**
       
     3  * Network API: WP_Network_Query class
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage Multisite
       
     7  * @since 4.6.0
       
     8  */
       
     9 
       
    10 /**
       
    11  * Core class used for querying networks.
       
    12  *
       
    13  * @since 4.6.0
       
    14  *
       
    15  * @see WP_Network_Query::__construct() for accepted arguments.
       
    16  */
       
    17 class WP_Network_Query {
       
    18 
       
    19 	/**
       
    20 	 * SQL for database query.
       
    21 	 *
       
    22 	 * @since 4.6.0
       
    23 	 * @var string
       
    24 	 */
       
    25 	public $request;
       
    26 
       
    27 	/**
       
    28 	 * SQL query clauses.
       
    29 	 *
       
    30 	 * @since 4.6.0
       
    31 	 * @var array
       
    32 	 */
       
    33 	protected $sql_clauses = array(
       
    34 		'select'  => '',
       
    35 		'from'    => '',
       
    36 		'where'   => array(),
       
    37 		'groupby' => '',
       
    38 		'orderby' => '',
       
    39 		'limits'  => '',
       
    40 	);
       
    41 
       
    42 	/**
       
    43 	 * Query vars set by the user.
       
    44 	 *
       
    45 	 * @since 4.6.0
       
    46 	 * @var array
       
    47 	 */
       
    48 	public $query_vars;
       
    49 
       
    50 	/**
       
    51 	 * Default values for query vars.
       
    52 	 *
       
    53 	 * @since 4.6.0
       
    54 	 * @var array
       
    55 	 */
       
    56 	public $query_var_defaults;
       
    57 
       
    58 	/**
       
    59 	 * List of networks located by the query.
       
    60 	 *
       
    61 	 * @since 4.6.0
       
    62 	 * @var array
       
    63 	 */
       
    64 	public $networks;
       
    65 
       
    66 	/**
       
    67 	 * The amount of found networks for the current query.
       
    68 	 *
       
    69 	 * @since 4.6.0
       
    70 	 * @var int
       
    71 	 */
       
    72 	public $found_networks = 0;
       
    73 
       
    74 	/**
       
    75 	 * The number of pages.
       
    76 	 *
       
    77 	 * @since 4.6.0
       
    78 	 * @var int
       
    79 	 */
       
    80 	public $max_num_pages = 0;
       
    81 
       
    82 	/**
       
    83 	 * Constructor.
       
    84 	 *
       
    85 	 * Sets up the network query, based on the query vars passed.
       
    86 	 *
       
    87 	 * @since 4.6.0
       
    88 	 *
       
    89 	 * @param string|array $query {
       
    90 	 *     Optional. Array or query string of network query parameters. Default empty.
       
    91 	 *
       
    92 	 *     @type array        $network__in          Array of network IDs to include. Default empty.
       
    93 	 *     @type array        $network__not_in      Array of network IDs to exclude. Default empty.
       
    94  	 *     @type bool         $count                Whether to return a network count (true) or array of network objects.
       
    95  	 *                                              Default false.
       
    96  	 *     @type string       $fields               Network fields to return. Accepts 'ids' (returns an array of network IDs)
       
    97  	 *                                              or empty (returns an array of complete network objects). Default empty.
       
    98  	 *     @type int          $number               Maximum number of networks to retrieve. Default empty (no limit).
       
    99  	 *     @type int          $offset               Number of networks to offset the query. Used to build LIMIT clause.
       
   100  	 *                                              Default 0.
       
   101  	 *     @type bool         $no_found_rows        Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
       
   102  	 *     @type string|array $orderby              Network status or array of statuses. Accepts 'id', 'domain', 'path',
       
   103  	 *                                              'domain_length', 'path_length' and 'network__in'. Also accepts false,
       
   104  	 *                                              an empty array, or 'none' to disable `ORDER BY` clause. Default 'id'.
       
   105  	 *     @type string       $order                How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'.
       
   106  	 *     @type string       $domain               Limit results to those affiliated with a given domain. Default empty.
       
   107  	 *     @type array        $domain__in           Array of domains to include affiliated networks for. Default empty.
       
   108  	 *     @type array        $domain__not_in       Array of domains to exclude affiliated networks for. Default empty.
       
   109  	 *     @type string       $path                 Limit results to those affiliated with a given path. Default empty.
       
   110  	 *     @type array        $path__in             Array of paths to include affiliated networks for. Default empty.
       
   111  	 *     @type array        $path__not_in         Array of paths to exclude affiliated networks for. Default empty.
       
   112  	 *     @type string       $search               Search term(s) to retrieve matching networks for. Default empty.
       
   113 	 *     @type bool         $update_network_cache Whether to prime the cache for found networks. Default true.
       
   114 	 * }
       
   115 	 */
       
   116 	public function __construct( $query = '' ) {
       
   117 		$this->query_var_defaults = array(
       
   118 			'network__in'          => '',
       
   119 			'network__not_in'      => '',
       
   120 			'count'                => false,
       
   121 			'fields'               => '',
       
   122 			'number'               => '',
       
   123 			'offset'               => '',
       
   124 			'no_found_rows'        => true,
       
   125 			'orderby'              => 'id',
       
   126 			'order'                => 'ASC',
       
   127 			'domain'               => '',
       
   128 			'domain__in'           => '',
       
   129 			'domain__not_in'       => '',
       
   130 			'path'                 => '',
       
   131 			'path__in'             => '',
       
   132 			'path__not_in'         => '',
       
   133 			'search'               => '',
       
   134 			'update_network_cache' => true,
       
   135 		);
       
   136 
       
   137 		if ( ! empty( $query ) ) {
       
   138 			$this->query( $query );
       
   139 		}
       
   140 	}
       
   141 
       
   142 	/**
       
   143 	 * Parses arguments passed to the network query with default query parameters.
       
   144 	 *
       
   145 	 * @since 4.6.0
       
   146 	 *
       
   147 	 *
       
   148 	 * @param string|array $query WP_Network_Query arguments. See WP_Network_Query::__construct()
       
   149 	 */
       
   150 	public function parse_query( $query = '' ) {
       
   151 		if ( empty( $query ) ) {
       
   152 			$query = $this->query_vars;
       
   153 		}
       
   154 
       
   155 		$this->query_vars = wp_parse_args( $query, $this->query_var_defaults );
       
   156 
       
   157 		/**
       
   158 		 * Fires after the network query vars have been parsed.
       
   159 		 *
       
   160 		 * @since 4.6.0
       
   161 		 *
       
   162 		 * @param WP_Network_Query $this The WP_Network_Query instance (passed by reference).
       
   163 		 */
       
   164 		do_action_ref_array( 'parse_network_query', array( &$this ) );
       
   165 	}
       
   166 
       
   167 	/**
       
   168 	 * Sets up the WordPress query for retrieving networks.
       
   169 	 *
       
   170 	 * @since 4.6.0
       
   171 	 *
       
   172 	 * @param string|array $query Array or URL query string of parameters.
       
   173 	 * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids',
       
   174 	 *                   or the number of networks when 'count' is passed as a query var.
       
   175 	 */
       
   176 	public function query( $query ) {
       
   177 		$this->query_vars = wp_parse_args( $query );
       
   178 		return $this->get_networks();
       
   179 	}
       
   180 
       
   181 	/**
       
   182 	 * Gets a list of networks matching the query vars.
       
   183 	 *
       
   184 	 * @since 4.6.0
       
   185 	 *
       
   186 	 * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids',
       
   187 	 *                   or the number of networks when 'count' is passed as a query var.
       
   188 	 */
       
   189 	public function get_networks() {
       
   190 		$this->parse_query();
       
   191 
       
   192 		/**
       
   193 		 * Fires before networks are retrieved.
       
   194 		 *
       
   195 		 * @since 4.6.0
       
   196 		 *
       
   197 		 * @param WP_Network_Query $this Current instance of WP_Network_Query (passed by reference).
       
   198 		 */
       
   199 		do_action_ref_array( 'pre_get_networks', array( &$this ) );
       
   200 
       
   201 		// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
       
   202 		$_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) );
       
   203 
       
   204 		// Ignore the $fields argument as the queried result will be the same regardless.
       
   205 		unset( $_args['fields'] );
       
   206 
       
   207 		$key = md5( serialize( $_args ) );
       
   208 		$last_changed = wp_cache_get_last_changed( 'networks' );
       
   209 
       
   210 		$cache_key = "get_network_ids:$key:$last_changed";
       
   211 		$cache_value = wp_cache_get( $cache_key, 'networks' );
       
   212 
       
   213 		if ( false === $cache_value ) {
       
   214 			$network_ids = $this->get_network_ids();
       
   215 			if ( $network_ids ) {
       
   216 				$this->set_found_networks();
       
   217 			}
       
   218 
       
   219 			$cache_value = array(
       
   220 				'network_ids' => $network_ids,
       
   221 				'found_networks' => $this->found_networks,
       
   222 			);
       
   223 			wp_cache_add( $cache_key, $cache_value, 'networks' );
       
   224 		} else {
       
   225 			$network_ids = $cache_value['network_ids'];
       
   226 			$this->found_networks = $cache_value['found_networks'];
       
   227 		}
       
   228 
       
   229 		if ( $this->found_networks && $this->query_vars['number'] ) {
       
   230 			$this->max_num_pages = ceil( $this->found_networks / $this->query_vars['number'] );
       
   231 		}
       
   232 
       
   233 		// If querying for a count only, there's nothing more to do.
       
   234 		if ( $this->query_vars['count'] ) {
       
   235 			// $network_ids is actually a count in this case.
       
   236 			return intval( $network_ids );
       
   237 		}
       
   238 
       
   239 		$network_ids = array_map( 'intval', $network_ids );
       
   240 
       
   241 		if ( 'ids' == $this->query_vars['fields'] ) {
       
   242 			$this->networks = $network_ids;
       
   243 			return $this->networks;
       
   244 		}
       
   245 
       
   246 		if ( $this->query_vars['update_network_cache'] ) {
       
   247 			_prime_network_caches( $network_ids );
       
   248 		}
       
   249 
       
   250 		// Fetch full network objects from the primed cache.
       
   251 		$_networks = array();
       
   252 		foreach ( $network_ids as $network_id ) {
       
   253 			if ( $_network = get_network( $network_id ) ) {
       
   254 				$_networks[] = $_network;
       
   255 			}
       
   256 		}
       
   257 
       
   258 		/**
       
   259 		 * Filters the network query results.
       
   260 		 *
       
   261 		 * @since 4.6.0
       
   262 		 *
       
   263 		 * @param array            $_networks An array of WP_Network objects.
       
   264 		 * @param WP_Network_Query $this      Current instance of WP_Network_Query (passed by reference).
       
   265 		 */
       
   266 		$_networks = apply_filters_ref_array( 'the_networks', array( $_networks, &$this ) );
       
   267 
       
   268 		// Convert to WP_Network instances
       
   269 		$this->networks = array_map( 'get_network', $_networks );
       
   270 
       
   271 		return $this->networks;
       
   272 	}
       
   273 
       
   274 	/**
       
   275 	 * Used internally to get a list of network IDs matching the query vars.
       
   276 	 *
       
   277 	 * @since 4.6.0
       
   278 	 *
       
   279 	 * @global wpdb $wpdb WordPress database abstraction object.
       
   280 	 *
       
   281 	 * @return int|array A single count of network IDs if a count query. An array of network IDs if a full query.
       
   282 	 */
       
   283 	protected function get_network_ids() {
       
   284 		global $wpdb;
       
   285 
       
   286 		$order = $this->parse_order( $this->query_vars['order'] );
       
   287 
       
   288 		// Disable ORDER BY with 'none', an empty array, or boolean false.
       
   289 		if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) {
       
   290 			$orderby = '';
       
   291 		} elseif ( ! empty( $this->query_vars['orderby'] ) ) {
       
   292 			$ordersby = is_array( $this->query_vars['orderby'] ) ?
       
   293 				$this->query_vars['orderby'] :
       
   294 				preg_split( '/[,\s]/', $this->query_vars['orderby'] );
       
   295 
       
   296 			$orderby_array = array();
       
   297 			foreach ( $ordersby as $_key => $_value ) {
       
   298 				if ( ! $_value ) {
       
   299 					continue;
       
   300 				}
       
   301 
       
   302 				if ( is_int( $_key ) ) {
       
   303 					$_orderby = $_value;
       
   304 					$_order = $order;
       
   305 				} else {
       
   306 					$_orderby = $_key;
       
   307 					$_order = $_value;
       
   308 				}
       
   309 
       
   310 				$parsed = $this->parse_orderby( $_orderby );
       
   311 
       
   312 				if ( ! $parsed ) {
       
   313 					continue;
       
   314 				}
       
   315 
       
   316 				if ( 'network__in' === $_orderby ) {
       
   317 					$orderby_array[] = $parsed;
       
   318 					continue;
       
   319 				}
       
   320 
       
   321 				$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
       
   322 			}
       
   323 
       
   324 			$orderby = implode( ', ', $orderby_array );
       
   325 		} else {
       
   326 			$orderby = "$wpdb->site.id $order";
       
   327 		}
       
   328 
       
   329 		$number = absint( $this->query_vars['number'] );
       
   330 		$offset = absint( $this->query_vars['offset'] );
       
   331 
       
   332 		if ( ! empty( $number ) ) {
       
   333 			if ( $offset ) {
       
   334 				$limits = 'LIMIT ' . $offset . ',' . $number;
       
   335 			} else {
       
   336 				$limits = 'LIMIT ' . $number;
       
   337 			}
       
   338 		}
       
   339 
       
   340 		if ( $this->query_vars['count'] ) {
       
   341 			$fields = 'COUNT(*)';
       
   342 		} else {
       
   343 			$fields = "$wpdb->site.id";
       
   344 		}
       
   345 
       
   346 		// Parse network IDs for an IN clause.
       
   347 		if ( ! empty( $this->query_vars['network__in'] ) ) {
       
   348 			$this->sql_clauses['where']['network__in'] = "$wpdb->site.id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__in'] ) ) . ' )';
       
   349 		}
       
   350 
       
   351 		// Parse network IDs for a NOT IN clause.
       
   352 		if ( ! empty( $this->query_vars['network__not_in'] ) ) {
       
   353 			$this->sql_clauses['where']['network__not_in'] = "$wpdb->site.id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__not_in'] ) ) . ' )';
       
   354 		}
       
   355 
       
   356 		if ( ! empty( $this->query_vars['domain'] ) ) {
       
   357 			$this->sql_clauses['where']['domain'] = $wpdb->prepare( "$wpdb->site.domain = %s", $this->query_vars['domain'] );
       
   358 		}
       
   359 
       
   360 		// Parse network domain for an IN clause.
       
   361 		if ( is_array( $this->query_vars['domain__in'] ) ) {
       
   362 			$this->sql_clauses['where']['domain__in'] = "$wpdb->site.domain IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__in'] ) ) . "' )";
       
   363 		}
       
   364 
       
   365 		// Parse network domain for a NOT IN clause.
       
   366 		if ( is_array( $this->query_vars['domain__not_in'] ) ) {
       
   367 			$this->sql_clauses['where']['domain__not_in'] = "$wpdb->site.domain NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__not_in'] ) ) . "' )";
       
   368 		}
       
   369 
       
   370 		if ( ! empty( $this->query_vars['path'] ) ) {
       
   371 			$this->sql_clauses['where']['path'] = $wpdb->prepare( "$wpdb->site.path = %s", $this->query_vars['path'] );
       
   372 		}
       
   373 
       
   374 		// Parse network path for an IN clause.
       
   375 		if ( is_array( $this->query_vars['path__in'] ) ) {
       
   376 			$this->sql_clauses['where']['path__in'] = "$wpdb->site.path IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__in'] ) ) . "' )";
       
   377 		}
       
   378 
       
   379 		// Parse network path for a NOT IN clause.
       
   380 		if ( is_array( $this->query_vars['path__not_in'] ) ) {
       
   381 			$this->sql_clauses['where']['path__not_in'] = "$wpdb->site.path NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__not_in'] ) ) . "' )";
       
   382 		}
       
   383 
       
   384 		// Falsey search strings are ignored.
       
   385 		if ( strlen( $this->query_vars['search'] ) ) {
       
   386 			$this->sql_clauses['where']['search'] = $this->get_search_sql(
       
   387 				$this->query_vars['search'],
       
   388 				array( "$wpdb->site.domain", "$wpdb->site.path" )
       
   389 			);
       
   390 		}
       
   391 
       
   392 		$join = '';
       
   393 
       
   394 		$where = implode( ' AND ', $this->sql_clauses['where'] );
       
   395 
       
   396 		$pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
       
   397 
       
   398 		/**
       
   399 		 * Filters the network query clauses.
       
   400 		 *
       
   401 		 * @since 4.6.0
       
   402 		 *
       
   403 		 * @param array            $pieces A compacted array of network query clauses.
       
   404 		 * @param WP_Network_Query $this   Current instance of WP_Network_Query (passed by reference).
       
   405 		 */
       
   406 		$clauses = apply_filters_ref_array( 'networks_clauses', array( compact( $pieces ), &$this ) );
       
   407 
       
   408 		$fields = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
       
   409 		$join = isset( $clauses['join'] ) ? $clauses['join'] : '';
       
   410 		$where = isset( $clauses['where'] ) ? $clauses['where'] : '';
       
   411 		$orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
       
   412 		$limits = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
       
   413 		$groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : '';
       
   414 
       
   415 		if ( $where ) {
       
   416 			$where = 'WHERE ' . $where;
       
   417 		}
       
   418 
       
   419 		if ( $groupby ) {
       
   420 			$groupby = 'GROUP BY ' . $groupby;
       
   421 		}
       
   422 
       
   423 		if ( $orderby ) {
       
   424 			$orderby = "ORDER BY $orderby";
       
   425 		}
       
   426 
       
   427 		$found_rows = '';
       
   428 		if ( ! $this->query_vars['no_found_rows'] ) {
       
   429 			$found_rows = 'SQL_CALC_FOUND_ROWS';
       
   430 		}
       
   431 
       
   432 		$this->sql_clauses['select']  = "SELECT $found_rows $fields";
       
   433 		$this->sql_clauses['from']    = "FROM $wpdb->site $join";
       
   434 		$this->sql_clauses['groupby'] = $groupby;
       
   435 		$this->sql_clauses['orderby'] = $orderby;
       
   436 		$this->sql_clauses['limits']  = $limits;
       
   437 
       
   438 		$this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['groupby']} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}";
       
   439 
       
   440 		if ( $this->query_vars['count'] ) {
       
   441 			return intval( $wpdb->get_var( $this->request ) );
       
   442 		}
       
   443 
       
   444 		$network_ids = $wpdb->get_col( $this->request );
       
   445 
       
   446 		return array_map( 'intval', $network_ids );
       
   447 	}
       
   448 
       
   449 	/**
       
   450 	 * Populates found_networks and max_num_pages properties for the current query
       
   451 	 * if the limit clause was used.
       
   452 	 *
       
   453 	 * @since 4.6.0
       
   454 	 *
       
   455 	 * @global wpdb $wpdb WordPress database abstraction object.
       
   456 	 */
       
   457 	private function set_found_networks() {
       
   458 		global $wpdb;
       
   459 
       
   460 		if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) {
       
   461 			/**
       
   462 			 * Filters the query used to retrieve found network count.
       
   463 			 *
       
   464 			 * @since 4.6.0
       
   465 			 *
       
   466 			 * @param string           $found_networks_query SQL query. Default 'SELECT FOUND_ROWS()'.
       
   467 			 * @param WP_Network_Query $network_query        The `WP_Network_Query` instance.
       
   468 			 */
       
   469 			$found_networks_query = apply_filters( 'found_networks_query', 'SELECT FOUND_ROWS()', $this );
       
   470 
       
   471 			$this->found_networks = (int) $wpdb->get_var( $found_networks_query );
       
   472 		}
       
   473 	}
       
   474 
       
   475 	/**
       
   476 	 * Used internally to generate an SQL string for searching across multiple columns.
       
   477 	 *
       
   478 	 * @since 4.6.0
       
   479 	 *
       
   480 	 * @global wpdb  $wpdb WordPress database abstraction object.
       
   481 	 *
       
   482 	 * @param string $string  Search string.
       
   483 	 * @param array  $columns Columns to search.
       
   484 	 *
       
   485 	 * @return string Search SQL.
       
   486 	 */
       
   487 	protected function get_search_sql( $string, $columns ) {
       
   488 		global $wpdb;
       
   489 
       
   490 		$like = '%' . $wpdb->esc_like( $string ) . '%';
       
   491 
       
   492 		$searches = array();
       
   493 		foreach ( $columns as $column ) {
       
   494 			$searches[] = $wpdb->prepare( "$column LIKE %s", $like );
       
   495 		}
       
   496 
       
   497 		return '(' . implode( ' OR ', $searches ) . ')';
       
   498 	}
       
   499 
       
   500 	/**
       
   501 	 * Parses and sanitizes 'orderby' keys passed to the network query.
       
   502 	 *
       
   503 	 * @since 4.6.0
       
   504 	 *
       
   505 	 * @global wpdb $wpdb WordPress database abstraction object.
       
   506 	 *
       
   507 	 * @param string $orderby Alias for the field to order by.
       
   508 	 * @return string|false Value to used in the ORDER clause. False otherwise.
       
   509 	 */
       
   510 	protected function parse_orderby( $orderby ) {
       
   511 		global $wpdb;
       
   512 
       
   513 		$allowed_keys = array(
       
   514 			'id',
       
   515 			'domain',
       
   516 			'path',
       
   517 		);
       
   518 
       
   519 		$parsed = false;
       
   520 		if ( $orderby == 'network__in' ) {
       
   521 			$network__in = implode( ',', array_map( 'absint', $this->query_vars['network__in'] ) );
       
   522 			$parsed = "FIELD( {$wpdb->site}.id, $network__in )";
       
   523 		} elseif ( $orderby == 'domain_length' || $orderby == 'path_length' ) {
       
   524 			$field = substr( $orderby, 0, -7 );
       
   525 			$parsed = "CHAR_LENGTH($wpdb->site.$field)";
       
   526 		} elseif ( in_array( $orderby, $allowed_keys ) ) {
       
   527 			$parsed = "$wpdb->site.$orderby";
       
   528 		}
       
   529 
       
   530 		return $parsed;
       
   531 	}
       
   532 
       
   533 	/**
       
   534 	 * Parses an 'order' query variable and cast it to 'ASC' or 'DESC' as necessary.
       
   535 	 *
       
   536 	 * @since 4.6.0
       
   537 	 *
       
   538 	 * @param string $order The 'order' query variable.
       
   539 	 * @return string The sanitized 'order' query variable.
       
   540 	 */
       
   541 	protected function parse_order( $order ) {
       
   542 		if ( ! is_string( $order ) || empty( $order ) ) {
       
   543 			return 'ASC';
       
   544 		}
       
   545 
       
   546 		if ( 'ASC' === strtoupper( $order ) ) {
       
   547 			return 'ASC';
       
   548 		} else {
       
   549 			return 'DESC';
       
   550 		}
       
   551 	}
       
   552 }