Inventory_Presser_Plugin::modify_query_orderby( array $pieces )

Filter callback. Modifies a query’s ORDER BY clause to appropriately sort some meta values as numbers instead of strings while adding fields to the ORDER BY clause to account for all of the JOINs to the postmeta.


Parameters

$pieces

(array) (Required) All of a queries syntax organized into an array.


Return

(array) The changed array of database query fragments


Source

File: inventory-presser.php

		public function modify_query_orderby( $pieces ) {
			/**
			 * Count the number of meta fields we have added to the query by parsing
			 * the join piece of the query
			 */
			global $wpdb;
			$meta_field_count = count( explode( "INNER JOIN $wpdb->postmeta AS", $pieces['join'] ) ) - 1;

			// Parse out the ASC or DESC sort direction from the end of the ORDER BY clause.
			$direction             = $this->get_last_word( $pieces['orderby'] );
			$acceptable_directions = array( 'ASC', 'DESC' );
			$direction             = ( in_array( $direction, $acceptable_directions, true ) ? ' ' . $direction : '' );

			/**
			 * Build a string to replace the existing ORDER BY field name
			 * Essentially, we are going to turn '{$wpdb->postmeta}.meta_value' into
			 * 'mt1.meta_value ASC, mt2.meta_value ASC, mt3.meta_value ASC'
			 * where the number of meta values is what we calculated in $meta_field_count
			 */
			if ( 0 < $meta_field_count ) {
				$replacement = $pieces['orderby'] . ', ';
				for ( $m = 0; $m < $meta_field_count; $m++ ) {
					$replacement .= 'mt' . ( $m + 1 ) . '.meta_value';
					/**
					 * Determine if this meta field should be sorted as a number
					 * 1. Parse out the meta key name from $pieces['where']
					 * 2. Run it through INVP::meta_value_is_number
					 */
					$field_start = strpos( $pieces['where'] ?? '', 'mt' . ( $m + 1 ) . '.meta_key = \'' ) + 16;
					$field_end   = strpos( $pieces['where'] ?? '', "'", $field_start ) - $field_start;
					if ( is_integer( $field_start ) && is_integer( $field_end ) ) {
						$field_name  = substr( $pieces['where'], $field_start, $field_end );
						if ( INVP::meta_value_is_number( $field_name ) ) {
							$replacement .= '+0';
						}
					}

					$replacement .= $direction;
					if ( $m < ( $meta_field_count - 1 ) ) {
						$replacement .= ', ';
					}
				}

				$pieces['orderby'] = $replacement;
			}
			return $pieces;
		}