WC_Admin_List_Table_Products::filter_stock_status_post_clauses │ public │ WC 1.0

Filter by stock status.

Method of the class: WC_Admin_List_Table_Products{}

No Hooks.

Returns

array.

Usage

$WC_Admin_List_Table_Products = new WC_Admin_List_Table_Products();
$WC_Admin_List_Table_Products->filter_stock_status_post_clauses( $args );
$args(array) (required)
Query args.

WC_Admin_List_Table_Products::filter_stock_status_post_clauses() code WC 11.1.2

public function filter_stock_status_post_clauses( $args ) {
	global $wpdb;
	if ( ! empty( $_GET['stock_status'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		// Join before looking at the value at all. This filter is registered on a non-empty raw
		// stock_status, and has joined the lookup table for every such request since the feature
		// shipped; callbacks running after it rely on the alias existing. Values that normalise to
		// nothing ( ' ', '<b>', 'stock_status[]=' ) still reach here, so deciding the join after
		// normalising would drop it for exactly the requests that used to keep it.
		$args['join'] = $this->append_product_sorting_table_join( $args['join'] ?? '' );

		$stock_status = wc_clean( wp_unslash( $_GET['stock_status'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		// The request can shape this as an array, but the filter only ever describes a single
		// status, so the first value wins. That is deliberate: multi-value requests previously
		// matched the whole catalogue, because wpdb::prepare() rejects the surplus argument and
		// returns no clause at all. Anything that is still not a string normalises to '', which
		// matches no product -- the behaviour those requests have always had.
		if ( is_array( $stock_status ) ) {
			$stock_status = reset( $stock_status );
		}
		if ( ! is_string( $stock_status ) ) {
			$stock_status = '';
		}

		if ( ProductStockStatus::OUT_OF_STOCK === $stock_status ) {
			// Only published variations qualify their parent for this discoverability filter.
			// Other statuses retain normal aggregate-parent behavior.
			$args['where'] .= $wpdb->prepare(
				" AND {$wpdb->posts}.ID IN (
					SELECT stock_status_products.product_id
					FROM (
						SELECT DISTINCT CAST(
							CASE
								WHEN stock_status_posts.post_type = 'product_variation' THEN stock_status_posts.post_parent
								ELSE stock_status_lookup.product_id
							END AS UNSIGNED
						) AS product_id
						FROM {$wpdb->wc_product_meta_lookup} stock_status_lookup
						INNER JOIN {$wpdb->posts} stock_status_posts
							ON stock_status_posts.ID = stock_status_lookup.product_id
						WHERE stock_status_lookup.stock_status = %s
							AND (
								stock_status_posts.post_type = 'product'
								OR (
									stock_status_posts.post_type = 'product_variation'
									AND stock_status_posts.post_status = 'publish'
								)
							)
					) stock_status_products
				) ",
				$stock_status
			);
		} else {
			$args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_status=%s ', $stock_status );
		}
	}
	return $args;
}