1

I need to create a block from a cronjob that render products grid (yes I know it sound weird), and get the output html. To do so I created a custom block with template and tried to use it like this (reminder: from a cronjob):

$block = Mage::app()->getLayout()->createBlock('my_special_block')
                        ->setTemplate('my_special_template.phtml');
Mage::log($block->toHtml());

This returned the html of a product grids with products in it, but they looked nothing like the actual site products. So I tried using this code in a controller, something like this:

$block = $this->getLayout()->createBlock('my_special_block')
                            ->setTemplate('my_special_template.phtml');
echo $block->toHtml();

And indeed the html I get when going to the controller url is totally different than the one I got from the cron.

My guess is that when I get the layout in the cron, Magento don't load all the layout updates or something like that. but I couldn't find info in the docs of how to do it. Or maybe its a different problem?

Any solution would be appreciated, I just need to get my hands on the correct html from inside the cron.

EDIT: Tried adding these lines before creating the block in the cronjob, but the html still looks different. :/

    Mage::app()->setCurrentStore(0);
    $layout = Mage::app()->getLayout();
    $layout->getUpdate()->addHandle('default')->load();

Thanks!

2
  • Sounds like a store init is missing, could you post the full code from your cron file ? – Raphael at Digital Pianism Mar 8 '16 at 16:38
  • this is the entire cron code that produce the wrong htmls (for the sake of debugging this problem I created a test cron function with the lines above). what do you mean by init the store? – Ronen Ness Mar 8 '16 at 16:45
2

Magento don't load all the layout updates or something like that.

Of course not, because why should Magento load frontend layout updates in the cron? But that's not your problem, because you don't use any of the layout updates (i.e. the XML that you would load with loadLayout() in the controller), but create a standalone block.

Setting a store is not the worst idea, but do not use the admin store (id 0):

Mage::app()->setCurrentStore(0);

But instead the default frontend store (or another specific one, depends what you need):

Mage::app()->setCurrentStore(1);

Additionally, you might need to set the frontend area:

Mage::getDesign()->setArea('frontend');

Alternative

One possible problem with this approach is that in the same process, other cronjobs will be executed and setting the store might have side effects on them.

There is another option, which is also used to render emails sent from cron or admin: Store Emulation

Start Emulation:

$storeId = 1;

$initialEnvironmentInfo = Mage::getSingleton('core/app_emulation')->startEnvironmentEmulation($storeId);
Mage::getDesign()->setStore($storeId);
Mage::getDesign()->setTheme(Mage::getStoreConfig('design/theme/default', $storeId));

Stop Emulation:

Mage::getSingleton('core/app_emulation')->stopEnvironmentEmulation($initialEnvironmentInfo);
5
  • Thanks fschmengler, I actually tried both approaches already but probably missed something because now Option 2 suddenly works! :). Option 1 doesn't work at all btw, even-though I think it should. One last thing though - I get images sources in "localhost" instead of the site ip / domain. Do you have any idea how to fix that? Thanks a lot! – Ronen Ness Mar 9 '16 at 13:50
  • Works for me with the following after starting store emulation: $store = Mage::app()->getStore($storeId); $store->setConfig('web/unsecure/base_skin_url', Mage::getStoreConfig('web/secure/base_skin_url', $storeId)); $store->setConfig('web/unsecure/base_media_url', Mage::getStoreConfig('web/secure/base_media_url', $storeId)); $store->setConfig('web/unsecure/base_js_url', Mage::getStoreConfig('web/secure/base_js_url', $storeId)); – Fabian Schmengler Mar 9 '16 at 13:54
  • mm I'm still getting urls in form of "localhost/..." strange. I also tried cleaning cache but it didn't work either. got more ideas maybe? Thanks! (you already helped a lot) – Ronen Ness Mar 9 '16 at 14:00
  • 1
    Not really, sorry. I would suspect something with a singleton that contains loaded values from something before this code, but don't know which one it could be. – Fabian Schmengler Mar 9 '16 at 14:04
  • ok I'll take a look. worse case I'll just replace all "localhost" with site base url and hope for the best :) – Ronen Ness Mar 9 '16 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.