2

I had a look around the site but can't find any existing threads would solve my problem. I have an extension to exclude some products and categories before rendering the sitemap.xml. I use Mage::log to record if those methods are fired.

While I tested on local machine, everything works fine. They correctly excluded some specified categories and products and also generated log files in /var/log folder.

When I deployed the codes onto the server, only method beforeLoadLayout worked and logs generated.

The methods excludeProductsFromSitemap and excludeCategoriesFromSitemap are not working at all. Neither logs generate.

  • Cache is flushed every time I update codes
  • Compilation is always disabled

Here is my config.xml

<?xml version="1.0"?>
<config>
<modules>
    <My_Ext>
        <version>0.1.2</version>
    </My_Ext>
</modules>
<global>
    <!-- models -->
    <models>
        <myext>
            <class>My_Ext_Model</class>
        </myext>
    </models>
    <!-- helpers -->
    <helpers>
        <myext>
            <class>My_Ext_Helper</class>
        </myext>
    </helpers>
    <events>
        <sitemap_products_generating_before>
            <observers>
                <myext>
                    <class>myext/observer</class>
                    <method>excludeProductsFromSitemap</method>
                </myext>
            </observers>
        </sitemap_products_generating_before>
        <sitemap_categories_generating_before>
            <observers>
                <myext>
                    <class>myext/observer</class>
                    <method>excludeCategoriesFromSitemap</method>
                </myext>
            </observers>
        </sitemap_categories_generating_before>
    </events>
</global>
<frontend>
    <events>
        <core_block_abstract_prepare_layout_before>
            <observers>
                <myext>
                    <type>model</type>
                    <class>myext/observer</class>
                    <method>beforeLoadLayout</method>
                </myext>
            </observers>
        </core_block_abstract_prepare_layout_before>
    </events>
</frontend>

I also tried other way to write the <events> like below but result is the same as above:

    <events>
        <sitemap_products_generating_before>
            <observers>
                <myext>
                    <class>My_Ext_Model_Observer</class>
                    <method>excludeProductsFromSitemap</method>
                </myext>
            </observers>
        </sitemap_products_generating_before>
        <sitemap_categories_generating_before>
            <observers>
                <myext>
                    <class>My_Ext_Model_Observer</class>
                    <method>excludeCategoriesFromSitemap</method>
                </myext>
            </observers>
        </sitemap_categories_generating_before>
    </events>

Here is my Observer.php:

<?php
class My_Ext_Model_Observer {
public function excludeCategoriesFromSitemap( Varien_Event_Observer $observer ) {
    Mage::log( 'in excludeCategoriesFromSitemap', null, '000_debug.log' );
    $event      = $observer->getEvent();
    $collection = $event->getCollection();
    $items      = $this->getFilteredItems( $observer, 'category' );
    $collection->setItems( $items );
}

public function excludeProductsFromSitemap( Varien_Event_Observer $observer ) {
    Mage::log( 'in excludeProductsFromSitemap', null, '000_debug.log' );
    $event      = $observer->getEvent();
    $collection = $event->getCollection();
    $items      = $this->getFilteredItems( $observer, 'product' );
    $collection->setItems( $items );
}

private function getFilteredItems( $observer, $type ) {
    // Not called by event directly and works fine so not copied
    return $items;
}

public function beforeLoadLayout( Varien_Event_Observer $observer ) {
    Mage::log( 'in beforeLoadLayout', null, '000_debug.log' );
    // Works find on local and server so not copied
}

}

I also tried to writing the class like class My_Ext_Model_Observer extends Mage_Core_Model_Observer but problem remains the same.

I appreciate if anyone can come up with anything I haven't tried. Lots of thanks.

  • 1
    Check this: magento.stackexchange.com/questions/4528/… – Adarsh Khatri Jun 13 '17 at 0:54
  • Thanks @adarsh-khatri, I will have a look of that one now. – noob Jun 13 '17 at 1:18
  • @adarsh-khatri, that actually works! Wonderfull! Thanks for the hint. I will come back and upvote your help when I have more rep. – noob Jun 13 '17 at 3:43
  • Glad it worked for you. – Adarsh Khatri Jun 13 '17 at 5:50
0

I found the solution with @adarsh-khatri's help.

First of all, using <rewrite> instead of firing an <event> before rendering the sitemap.xml. So I removed the events and methods then added rewrite as below:

app/code/local/My/Ext/config.xml

<conig>
...
<global>
    <!-- models -->
    <models>
        <canoupdater>
            <class>My_Ext_Model</class>
        </canoupdater>
        <sitemap_resource>
            <rewrite>
                <catalog_category>My_Ext_Model_Resource_Catalog_Category</catalog_category>
            </rewrite>
        </sitemap_resource>
        <sitemap_resource>
            <rewrite>
                <catalog_product>My_Ext_Model_Resource_Catalog_Product</catalog_product>
            </rewrite>
        </sitemap_resource>
    </models>
...
</global>
...
</config>

I then added two files:

app/code/local/My/Ext/Model/Resource/Catalog/Category.php

<?php
class My_Ext_Model_Resource_Catalog_Category extends Mage_Sitemap_Model_Resource_Catalog_Category {
/**
 * Get category collection array
 *
 * @param int $storeId
 * @return array
 */
public function getCollection( $storeId ) {
    /* @var $store Mage_Core_Model_Store */
    $store = Mage::app()->getStore($storeId);
    if (!$store) {
        return false;
    }

    $this->_select = $this->_getWriteAdapter()->select()
        ->from($this->getMainTable())
        ->where($this->getIdFieldName() . '=?', $store->getRootCategoryId());

    $categoryRow = $this->_getWriteAdapter()->fetchRow($this->_select);
    if (!$categoryRow) {
        return false;
    }

    $this->_select = $this->_getWriteAdapter()->select()
        ->from(array('main_table' => $this->getMainTable()), array($this->getIdFieldName()))
        ->where('main_table.path LIKE ?', $categoryRow['path'] . '/%');

    $storeId = (int)$store->getId();

    /** @var $urlRewrite Mage_Catalog_Helper_Category_Url_Rewrite_Interface */
    $urlRewrite = $this->_factory->getCategoryUrlRewriteHelper();
    $urlRewrite->joinTableToSelect($this->_select, $storeId);

    $this->_addFilter($storeId, 'is_active', 1);

    $entries = $this->_loadEntities();
    foreach ( $entries as $k => $v ) {
        $obj = Mage::getModel( 'catalog/category' )->load( $k );
        if ( // My logic is true ) {
            unset( $entries[$k] ); // Remove this entry from the array
        }
    }
    return $entries;
}

app/code/local/My/Ext/Model/Resource/Catalog/Product.php

<?php
class My_Ext_Model_Resource_Catalog_Product extends Mage_Sitemap_Model_Resource_Catalog_Product {
/**
 * Get product collection array
 *
 * @param int $storeId
 * @return array
 */
public function getCollection( $storeId ) {
    /* @var $store Mage_Core_Model_Store */
    $store = Mage::app()->getStore($storeId);
    if (!$store) {
        return false;
    }

    $this->_select = $this->_getWriteAdapter()->select()
        ->from(array('main_table' => $this->getMainTable()), array($this->getIdFieldName()))
        ->join(
            array('w' => $this->getTable('catalog/product_website')),
            'main_table.entity_id = w.product_id',
            array()
        )
        ->where('w.website_id=?', $store->getWebsiteId());

    $storeId = (int)$store->getId();

    /** @var $urlRewrite Mage_Catalog_Helper_Product_Url_Rewrite_Interface */
    $urlRewrite = $this->_factory->getProductUrlRewriteHelper();
    $urlRewrite->joinTableToSelect($this->_select, $storeId);

    $this->_addFilter($storeId, 'visibility',
        Mage::getSingleton('catalog/product_visibility')->getVisibleInSiteIds(), 'in'
    );
    $this->_addFilter($storeId, 'status',
        Mage::getSingleton('catalog/product_status')->getVisibleStatusIds(), 'in'
    );

    $entries = $this->_loadEntities();
    foreach ( $entries as $k => $v ) {
        $obj = Mage::getModel( 'catalog/product' )->load( $k );
        if ( // If my logic is true ) {
            unset( $entries[$k] ); // Remove the entry from the array
        }
    }
    return $entries;
}

This solved my problem and I hope this would help others who have the similar problems.

  • Please check you previous code ... using events is the right way to go. – sv3n Jun 13 '17 at 7:01
  • @sv3n, I believe using event will definitely work but at the moment I can't find where goes wrong. If you have any idea please state in comments or post in reply. I appreciate. – noob Jun 13 '17 at 9:15
  • Which Magento version do you use? – sv3n Jun 13 '17 at 9:51
  • Magento 1.9.13 Enterprise – noob Jun 13 '17 at 13:13
  • Can you please check Mage_Sitemap_Model_Sitemap or Enterprise_Sitemap_Model_Sitemap if there is any dispatchEvent in generateXml(). – sv3n Jun 13 '17 at 13:33

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.