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() )
			|| ! is_post_type_archive( INVP::POST_TYPE )
			|| ( empty( $_GET['orderby'] ) && empty( $this->settings['sort_vehicles_by'] ) )
		) {
			return;
		}

		add_filter( 'posts_clauses', array( $this, 'modify_query_orderby' ) );

		/**
		 * 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 = $this->settings['sort_vehicles_order'];
		if ( isset( $_GET['order'] ) ) {
			$direction = sanitize_text_field( wp_unslash( $_GET['order'] ) );
		}

		$key = $this->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->query_vars['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 'length':
			case 'hull_material':
				unset( $query->query_vars['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 );
	}