How to Check Whether a Block Exists Based on Its Type in Magento

cmscms-blockevent-observerlayoutmodule

This really confuses me !!

I came to a situation, where I need to create a new block (core/template block) programmatically, if there is CMS Block present in a page layout. In general case, according to my knowledge, there are two work around for this.

1. Add a block through layout

In most of the case, this would be the best idea to do this task. We can add a block to a page if an appropriate layout handle is available. But unfortunately, in my case, I dont have any static block specific layout handle available (for cms pages, we know there is cms_page handle). So I can't rely on this method

2. Use an observer

The second method would be listen to an appropriate observer. Again, I cannot find a static block based observer that get triggered during layout/block loading time. However there are some general observers that I can rely on. I think controller_action_layout_generate_blocks_before can use in my case. But here I am facing my real problem

My real Problem

So when I use controller_action_layout_generate_blocks_before event in my case, the problem is that, I cannot retrieve blocks based on their type. I can filter blocks based on their name, but not based on their type. ie

$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type

I cant rely on names in fact. Because I want to get all cms/block type blocks and add a new template after checking some of their custom property that I have set with static block

So how can I get all cms/block through an observer ? Is it even possible. Please share your thoughts.

Best Answer

Use this:

           <core_block_abstract_prepare_layout_before>
                <observers>
                    <ssd_test>
                        <class>ssd_test/observer</class>
                        <method>generateBlocks</method>
                        <type>singleton</type>
                    </ssd_test>
                </observers>
            </core_block_abstract_prepare_layout_before>

Observer:

public function generateBlocks($observer)
    {
        /**
         * @var $block Mage_Core_Block_Abstract
         */
        $block = $observer->getEvent()->getBlock();
        if ($block->getType() == 'cms/block') {
            //do something
        }
    }

Refer to protected function _toHtml() of the Mage_Cms_Block_Block if you want to do some changes.

Update (another solution)

    <controller_action_layout_generate_blocks_after>
        <observers>
            <ssd_test>
                <class>ssd_test/observer</class>
                <method>generateBlocks</method>
                <type>singleton</type>
            </ssd_test>
        </observers>
    </controller_action_layout_generate_blocks_after>

Observer.php:

public function generateBlocks($observer)
    {
        /**
         * @var $l Mage_Core_Model_Layout
         */
        $l = $observer->getEvent()->getLayout();

        $newBlock = $l->createBlock(
            'Mage_Core_Block_Template',
            'new_block_name_here',
            array('template' => 'some_template.phtml')
        );

        foreach ($l->getAllBlocks() as $block) {
            if ($block->getType() == 'cms/block') {
                $l->getBlock('some_block_name')->append($newBlock);
            }
        }
    }