Inventory_Presser_Plugin::add_orderby_to_query( object $query )

Filter callback that adds an ORDER BY clause to the main query when a user requests a list of vehicles.


Parameters Parameters

$query

(object) (Required) An instance of the WP_Query class.


Top ↑

Return Return

(void)


Top ↑

Source Source

File: inventory-presser.php

		public function add_orderby_to_query( $query ) {
			// Do not mess with the query if it's not the main one and our CPT.
			if ( apply_filters( 'invp_apply_orderby_to_main_query_only', true ) && ! $query->is_main_query() ) {
				return;
			}

			if ( ! is_post_type_archive( INVP::POST_TYPE ) ) {
				return;
			}

			add_filter( 'posts_clauses', array( $this, 'modify_query_orderby' ) );
			$settings = INVP::settings();

			if ( empty( $_GET['orderby'] ) && empty( $settings['sort_vehicles_by'] ) ) {
				return;
			}

			/**
			 * The field we want to order by is either in $_GET['orderby'] when
			 * the user has chosen to reorder posts or saved in the plugin
			 * settings 'default-sort-key.' The sort direction is in
			 * $_GET['order'] or 'sort_vehicles_order.'
			 */
			$direction = $settings['sort_vehicles_order'];
			if ( isset( $_GET['order'] ) ) {
				$direction = sanitize_text_field( wp_unslash( $_GET['order'] ) );
			}

			$key = $settings['sort_vehicles_by'];

			// Backwards compatibility for pre 13.7.1 when there was a bug.
			if ( 'date_entered' === $key ) {
				$key = 'post_date';
			}
			if ( 'last_modified' === $key ) {
				$key = 'post_modified';
			}

			if ( isset( $_GET['orderby'] ) ) {
				$key = sanitize_text_field( wp_unslash( $_GET['orderby'] ) );
			}

			// post_date and post_modified are not meta keys.
			if ( in_array( $key, array( 'post_date', 'post_modified' ), true ) ) {
				$query->set( 'orderby', $key );
				$query->set( 'order', $direction );
				return;
			}

			// Make sure the meta key has the prefix.
			$key = apply_filters( 'invp_prefix_meta_key', $key );
			$query->set( 'meta_key', $key );

			/**
			 * Maybe append to the meta_query if it is already set. If we are
			 * sorting by make, then we want to also add a secondary sort of model
			 * and a tertiary sort of trim. That's what users want. Apply the same
			 * logic to sorts by year and model.
			 */
			$old = $query->get( 'meta_query', array() );
			switch ( apply_filters( 'invp_unprefix_meta_key', $query->get( 'meta_key' ) ) ) {
				case 'make':
					$query->set(
						'meta_query',
						array_merge(
							$old,
							array(
								'relation' => 'AND',
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'EXISTS',
									),
								),
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'EXISTS',
									),
								),
							)
						)
					);
					break;

				case 'model':
					$query->set(
						'meta_query',
						array_merge(
							$old,
							array(
								'relation' => 'AND',
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'EXISTS',
									),
								),
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'EXISTS',
									),
								),
							)
						)
					);
					break;

				case 'year':
					$query->set(
						'meta_query',
						array_merge(
							$old,
							array(
								'relation' => 'AND',
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'year' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'year' ),
										'compare' => 'EXISTS',
									),
								),
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'make' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'make' ),
										'compare' => 'EXISTS',
									),
								),
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'model' ),
										'compare' => 'EXISTS',
									),
								),
								array(
									'relation' => 'OR',
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'NOT EXISTS',
									),
									array(
										'key'     => apply_filters( 'invp_prefix_meta_key', 'trim' ),
										'compare' => 'EXISTS',
									),
								),
							)
						)
					);
					break;

				// Boat fields might not exist on all vehicles. Do not require them.
				case 'beam':
				case 'condition_boat':
				case 'draft':
				case 'engine_count':
				case 'engine_make':
				case 'engine_model':
				case 'horsepower':
				case 'hull_material':
				case 'length':
					$query->set( 'meta_key', '' );
					$query->set(
						'meta_query',
						array_merge(
							$old,
							array(
								'relation' => 'OR',
								array(
									'key'     => $key,
									'compare' => 'NOT EXISTS',
								),
								array(
									'key'     => $key,
									'compare' => 'EXISTS',
								),
							)
						)
					);
					break;
			}

			$meta_value_or_meta_value_num = 'meta_value';
			$key_is_odometer              = apply_filters( 'invp_prefix_meta_key', 'odometer' ) === $key;

			if ( INVP::meta_value_is_number( $key ) || $key_is_odometer ) {
				$meta_value_or_meta_value_num .= '_num';
			}

			// Customize the ORDER BY to remove non-digits from the odometer.
			if ( $key_is_odometer ) {
				add_filter( 'posts_orderby', array( $this, 'change_order_by_for_odometer' ), 10, 2 );
			}

			// Allow other developers to decide if the post meta values are numbers.
			$query->set( 'orderby', apply_filters( 'invp_meta_value_or_meta_value_num', $meta_value_or_meta_value_num, $key ) );
			$query->set( 'order', $direction );
		}