Question

I have a situation that Tinybrick has referred to as "advanced hole punching" and I can't seem to get it to work. We recently installed the Subscriptions and Recurring Payments extension from Aheadworks. This extension allows customers to subscribe to products they buy on a regular basis and extends the functionality of the Recurring Profiles for PayPal. For this to work, the addtocart block on the product view pages needs to be dynamic. Depending on whether the customer is logged in and the specific details of the product in question determine what is displayed in the addtocart block.

Using the Lightspeed hole punching, I've been able to fill various dynamic blocks on the page (top links, header cart, related products, etc). The problem with this block is that it depends on the Mage::registry('current_product') value. When Lightspeed is returning a cached page, it doesn't run the full Magento code, and the current_product registry value isn't set. I can not find a way to make this work.

I sent an email to Tinybrick and got back the following response:

For advanced hole punching like this, you would have to make a call via API / SOAP in the Controller. Basically, you would make a call for whatever information you need, then use that information to display your dynamic content. I have personally never done it like this, but was informed by our lead developer that it can be done.

I responded asking for examples or more information but have not heard back yet. I figured I'd throw something up here to see if anyone has any experience with this and can offer some help.

Était-ce utile?

La solution

When lightspeed.php sees a corresponding cache file in var/lightspeed directory, it loads it and parses. Now it sees, that some content needs to be dynamic. So lightspeed.php makes a fake GET request to Magento via Mage::run() with changed $_REQUEST['URI'] before. Take a look at the following code:

lightspeed.php:

self::report("attempting to retrieve hole punched content from {$data[2]}");
$_SERVER['originalRequestUri'] = $_SERVER['REQUEST_URI'];
$_SERVER['REQUEST_URI'] = self::$request_path . "/" . $data[2];

You can see here how I copy $_SERVER['REQUEST_URI'] to $_SERVER['originalRequestUri']. Let's go next and take a look at

HoleController.php:

    $originalRequest = new Mage_Core_Controller_Request_Http('http://example' . $_SERVER['originalRequestUri']);
    $originalRequest->setPathInfo()->setDispatched(false);
    Mage::getModel('core/url_rewrite')->rewrite($originalRequest);

    $params = explode('/', $originalRequest->getPathInfo());
    /* IF YOU HAVE SOME ADDITONAL PARAMS PASSED AS /color/1/size/2, 
       THIS PARAMS SHOULD BE ALSO PARSED AND SET TO REQUEST OBJECT
    for ($i = 3, $l = sizeof($params); $i < $l; $i+=2) {
        $originalRequest->setParam($params[$i], isset($params[$i + 1]) ? $params[$i + 1] : '');
    }
    */

    if ($params[1] == 'product') { // if parsed URL is product view page URL
        $productId = $originalRequest->getParam('id');
        $product = Mage::getModel('catalog/product')->load($productId);
        Mage::register('current_product', $product);
    }

Yay! Now we have current_product in registry. You're able to create a block you need.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top