3
votes

i have a store with configurable and simple products (multiple colors). currently, we pick one of the simple product images and assign that to the configurable product, and that is what shows up on the list page. the problem is, if that particular color goes out of stock, we are stuck with an image that represents a product that's not available (and having to manually update that image).

is there a way to use the simple product image on the list page, while still allowing the ability to control which image is used? i know how to use the simple image on the list page, but i can't figure out how to specify WHICH simple image (currently i'm just grabbing the simple products and pulling the image from the first one in the list).

if i could find a way to sort the simple products within the configurable products (i.e., ensure that for product A, the simple products are sorted black, green, blue and for product B, the simple products are sorted green, blue, black), i think i could figure out the rest.

any ideas?

1

1 Answers

1
votes

figured it out. i added a new attribute for simple products called 'sort_order'. then, i overrode the Catalog/Product helper and added the following method:

  public function getSortedSimpleProducts($product) {
    $products = array();

    $allProducts = $product->getTypeInstance(true)->getUsedProducts(null, $product);

    foreach ($allProducts as $product) {
      if ($product->isSaleable()) {
        $products[] = $product;
      }
    }
    $sorted_products = array();
    $unsorted_products = array();

    foreach ($products as $simple_product) {
      $sort_order = $simple_product->getData('sort_order');
      if ($sort_order) {
        $sorted_products[$sort_order] = $simple_product;
      }
      else {
        $unsorted_products[] = $simple_product;
      }
    }

    $final_products = $sorted_products;
    if (count($unsorted_products) > 0) {
      $final_products = array_merge($sorted_products, $unsorted_products);
    }
    if (count($final_products) > 0) {
      sort($final_products);
    }

    return $final_products;

  }

then, in the list.phtml template, around this line:

<?php $i=0; foreach ($_productCollection as $_product): ?>

i added the following code:

$image_product = $_product;
$products = $this->helper('catalog/product')->getSortedSimpleProducts($_product);
if (count($products) > 0) {
  $image_product = $products[0];
}

and updated my image tag:

<img src="<?php echo $this->helper('catalog/image')->init($image_product, 'small_image')->resize(189,238); ?>" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" />

then i overrode Mage_Catalog_Block_Product_View_Type_Configurable in order to make getAllowProducts sort by the new sort order (which determines the sorting of the colors on the view page):

  public function getAllowProducts() {
    if (!$this->hasAllowProducts()) {
      $products = array();
      $allProducts = Mage::helper('catalog/product')->getSortedSimpleProducts($this->getProduct());
      foreach ($allProducts as $product) {
        if ($product->isSaleable()) {
          $products[] = $product;
        }
      }
      $this->setAllowProducts($products);
    }
    return $this->getData('allow_products');
  }

and then updated the media.phtml file:

$childProducts = $this->helper('catalog/product')->getSortedSimpleProducts($_product);

so that the product image would also use the same sort.

i'm hoping this doesn't have a huge impact on performance (client sort of indicated that this is a major requirement). it degrades nicely in case the client doesn't set the sort order on the simple products. and, if inventory goes out of stock, it'll show the image from the next in the sort order.

any critiques would be welcome!