Checkout – Change Template Based on Products in Cart

cartcheckoutonepage-checkoutproductstemplate

This is a weird request from a client, the products can be purchased with or without logos adding on to them. However, when a product which requires a logo is added to the cart the checkout process needs to be slightly different as additional costs will be added afterwards.

I've tried setting a new session in order to store whether the cart has a product which requires a logo in it and using various if statements to overcome this request, example:

            <?php foreach($this->getItems() as $_item): ?>
                <?php
                    $get_attributes = $_item->getProduct()->getTypeInstance(true)->getOrderOptions($_item->getProduct());
                    $attributes = $get_attributes['attributes_info'];
                    foreach($attributes as $attribute) {
                        if($attribute['value'] == 'Has Logo') {
                            $logo_cart = TRUE;
                        }
                    }
                ?>
                    <?php echo $this->getItemHtml($_item) ?>
                <?php endforeach ?>

Using the $logo_cart variable I set it in the core/session, then use:

Mage::getSingleton('core/session')->getLogoCart();

within if statements to change aspects of the checkout.

This is obviously not an ideal way of achieving this, especially since I am currently only setting the session once the customer hits the cart page so it's quite buggy if they're already on the checkout page.

Are there any suggestions on how I can achieve the above? I'm currently using the One Page Checkout module found here: http://www.magentocommerce.com/magento-connect/express-checkout-one-step-checkout.html

One method I've thought about is switching the entire template depending on what's in the cart, but I'm unsure which files I'd need to change within the module to achieve this.

EDIT:
Just to clarify, the entire process is to remain the same. I just need to remove a few options from the checkout, such as the shipping method, the review your order section, and display a new area, which are just template changes anyway.

Best Answer

The cleanest way to do this is will use observers and custom layout XML. For that you will need to create your own extension. Inchoo has a nice hello world article that should get you started and you can read more about observers in this Magento Board post.

You will need to hook the controller_action_layout_load_before event. Add this to your config.xml.

<controller_action_layout_load_before>
    <observers>
        <[module]>
            <type>singleton</type>
            <class>[module]/observer</class>
            <method>addLayoutHandleObserver</method>
        </[module]>
    </observers>
</controller_action_layout_load_before>

Your Observer would use your code to check for the specific product and if present add a layout handle to the generate Layout XML. This will enable us to target it from a layout xml file.

class [Namespace]_[Module]_Model_Observer
{
    public function addLayoutHandleObserver(Varien_Event_Observer $observer)
    {

        $items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();

        $logo_cart = false;
        foreach ($items as $_item) 
        {
            $get_attributes = $_item->getProduct()->getTypeInstance(true)->getOrderOptions($_item->getProduct());
            $attributes = $get_attributes['attributes_info'];
            foreach($attributes as $attribute) {
                if($attribute['value'] == 'Has Logo') {
                    $logo_cart = true;
                    break;
                }
            }
           if ($logo_cart) break;
        }

        if ($logo_cart)
        {
            $layout = $observer->getAction()->getLayout();
            $layout->getUpdate()->addHandle('checkout_has_logo');
            $layout->generateXml();
        }

        return $this;
    }
}

Now we can add some custom layout updates from, for example, the local.xml.

<checkout_has_logo>
    <reference name="checkout.onepage">
        <action method="setTemplate"><template>checkout/onepage_logo.phtml</template></action>
    </reference>
</checkout_has_logo>
Related Topic