// Custom WP Query with filters $args = array( 'post_type' => 'product_variation', 'posts_per_page' => 500, ); $query = new WP_Query($args); // Add custom join and where clause add_filter('posts_join', 'custom_join_query'); add_filter('posts_where', 'custom_where_query'); // Fetch posts $products = $query->get_posts(); // Remove filters after the query is executed remove_filter('posts_join', 'custom_join_query'); remove_filter('posts_where', 'custom_where_query'); // Custom Join to get data from parent product and its meta function custom_join_query($join) { global $wpdb; $join .= " LEFT JOIN {$wpdb->posts} AS parent ON parent.ID = {$wpdb->posts}.post_parent"; $join .= " LEFT JOIN {$wpdb->term_relationships} AS rel ON rel.object_id = parent.ID"; $join .= " LEFT JOIN {$wpdb->term_taxonomy} AS tax ON tax.term_taxonomy_id = rel.term_taxonomy_id"; $join .= " LEFT JOIN {$wpdb->terms} AS term ON term.term_id = tax.term_id"; $join .= " LEFT JOIN {$wpdb->postmeta} AS parent_meta ON parent_meta.post_id = parent.ID"; return $join; } // Custom Where Clause to exclude certain categories, meta values, and stock status function custom_where_query($where) { global $wpdb; $where .= " AND (term.slug NOT IN ('exclude-category-1', 'exclude-category-2'))"; // Exclude certain categories $where .= " AND (parent_meta.meta_key = '_stock_status' AND parent_meta.meta_value != 'onbackorder')"; // Exclude products on backorder return $where; } // Use $products as needed