title: Display all products and variations on the shop page, while maintaining pagination
body: <p>I need to display every product, and in case it's a variable product (e.g. multiple colors), each variation on the shop page.</p>
  
  <p>At first, I've wrote my own query to retrieve all variations if the product had them:</p>
  
  <pre><code>$product = get_product();
  global $variable_id;
  global $color;
  if ($product-&gt;product_type == "variable") {
      $variations = $product-&gt;get_available_variations();
      foreach ($variations as $variation) {
          $color = $variation["attributes"]["attribute_pa_colour"];
          $variable_id = $variation['variation_id'];
          wc_get_template_part('content', 'product');
      }
  } else {
      $variable_id = null;
      $color = null;
      wc_get_template_part('content', 'product');
  }
  </code></pre>
  
  <p>I set the global parameter for the variation and got the right image afterwards in another template file with success. </p>
  
  <p>The problem with this solution is that the pagination is broken (1 product appears multiple times).</p>
  
  <p>So, what I need to achieve is manipulating the main product query to select all products, where those who have variations must appear once for each variation with the correct image link and variation value (I need the info of the main product aswell to link to the correct page).
  This could be achieved by a <code>Left Join</code> on the same products table, based on <code>post_parent</code>. </p>
  
  <p>The key here is to keep the default woocommerce behavior. This is the woocommerce function to retrieve the products:</p>
  
  <pre><code>private function query_products( $args ) {
      // Set base query arguments
      $query_args = array(
          'fields'      =&gt; 'ids',
          'post_type'   =&gt; 'product',
          'post_status' =&gt; 'publish',
          'meta_query'  =&gt; array(),
      );
      if ( ! empty( $args['type'] ) ) {
          $types = explode( ',', $args['type'] );
          $query_args['tax_query'] = array(
              array(
                  'taxonomy' =&gt; 'product_type',
                  'field'    =&gt; 'slug',
                  'terms'    =&gt; $types,
              ),
          );
          unset( $args['type'] );
      }
  
      // Filter products by category
      if ( ! empty( $args['category'] ) ) {
          $query_args['product_cat'] = $args['category'];
      }
  
      // Filter by specific sku
      if ( ! empty( $args['sku'] ) ) {
          if ( ! is_array( $query_args['meta_query'] ) ) {
              $query_args['meta_query'] = array();
          }
          $query_args['meta_query'][] = array(
              'key'     =&gt; '_sku',
              'value'   =&gt; $args['sku'],
              'compare' =&gt; '='
          );
          $query_args['post_type'] = array( 'product', 'product_variation' );
      }
      $query_args = $this-&gt;merge_query_args( $query_args, $args );
      return new WP_Query( $query_args );
  }
  </code></pre>
  
  <p>So basically, I need to find a way to override this function, so that a <code>WP_Query</code> object is returned containing all 'simple' products and a product for each variation of all 'variable' products, while all parameters passed with <code>$args</code> keep working.</p>