add step to OPC without overriding: update section

2019-08-02 21:55发布

问题:

so this is a follow up question of this one.
I am adding a step before the shipping-methods by observer. I have a problem for getting the html used to update the step's tab content. Despite my best efforts it still loads the html of the shipping-method step instead of the html I want.
This is the code of the observer:

public function gotoViesStep($observer)
{
    $response = $observer->getEvent()->getControllerAction()->getResponse();
    $body = $response->getBody();
    $result = Mage::helper('core')->jsonDecode($body);

    if (in_array('error', $result)) {
        return;
    }

    //if conditions are met, go to vies check
    if ($result['goto_section'] == 'shipping_method') {
        $quote = Mage::getSingleton('checkout/session')->getQuote();
        $shippingAddress = $quote->getShippingAddress();
        $countryId = $shippingAddress->getCountryId();

        if (($countryId != 'BE') && ($this->_countryInEU($countryId))) {
            $result['goto_section'] = 'vies';
            $result['allow_sections'][] = 'vies';
            $result['country_id'] = $countryId;

            $result['update_section'] = array(
                    'name' => 'vies',
                    'html' => $this->_getViesHtml()
                );

            $response->setBody(Mage::helper('core')->jsonEncode($result));
        }
    }
}

protected function _getViesHtml()
{
    $layout = Mage::getSingleton('core/layout');
    $update = $layout->getUpdate();
    $update->load('checkout_onepage_vies');
    $layout->generateXml();
    $layout->generateBlocks();
    $output = $layout->getOutput();
    return $output;
}

and the layout.xml of that handle checkout_onepage_vies:

<checkout_onepage_vies>
    <remove name="right"/>
    <remove name="left"/>

    <block type="correctionvat/onepage_vies" name="root" output="toHtml" template="correctionvat/onepage/vies.phtml"/>
</checkout_onepage_vies>

If I put something directly instead of trying to load the block, it works. I.E., if, instead of 'html' => $this->_getViesHtml() I do 'html' => 'foobar', the content of the step is foobar.

So it's like as the output/layout/blocks is already charged by the OnepageController my attempt to re-charge it again fails.
Any thaughts?

回答1:

The problem you are facing is related to the list of added layout handles. You need to reset them before calling load() method. Also you need to reset updates array, that contain previously parsed xml by calling resetUpdates() method.

You getViesHtml() should look like the following in the end:

protected function _getViesHtml()
{
    $layout = Mage::getSingleton('core/layout');

    $layout->getUpdate()
         ->resetHandles()
         ->resetUpdates()
         ->load('checkout_onepage_vies');

    $layout->generateXml()
         ->generateBlocks();

    $output = $layout->getOutput();
    return $output;
}