I want to include those pages from my Magento website’s sitemap.xml which should not be indexed by search engines. For this I have copied Catalog/Category.php Cms/Page.php to my corresponding app/code/local directories and I’m modifying it.
I have modified the Page.php successfully to exclude specific CMS pages from my sitemap.xml. I followed the directions given here
As I’m not familiar with PHP, I don’t know what changes to make to adapt this solution for the Category.php file.
Here’s my present Category.php file which is not excluding any specific category pages I want from sitemap.xml:
<?php
class Mage_Sitemap_Model_Resource_Catalog_Category extends Mage_Core_Model_Resource_Db_Abstract
{
/**
* Collection Zend Db select
*
* @var Zend_Db_Select
*/
protected $_select;
/**
* Attribute cache
*
* @var array
*/
protected $_attributesCache = array();
/**
* Init resource model (catalog/category)
*
*/
protected function _construct()
{
$this->_init('catalog/category', 'entity_id');
}
/**
* Get category collection array
*
* @param unknown_type $storeId
* @return array
*/
public function getCollection($storeId)
{
$categories = array();
$store = Mage::app()->getStore($storeId);
/* @var $store Mage_Core_Model_Store */
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;
}
$urConditions = array(
'e.entity_id=ur.category_id',
$this->_getWriteAdapter()->quoteInto('ur.store_id=?', $store->getId()),
'ur.product_id IS NULL',
$this->_getWriteAdapter()->quoteInto('ur.is_system=?', 1),
);
$this->_select = $this->_getWriteAdapter()->select()
->from(array('e' => $this->getMainTable()), array($this->getIdFieldName()))
->joinLeft(
array('ur' => $this->getTable('core/url_rewrite')),
join(' AND ', $urConditions),
array('url'=>'request_path')
)
->where('e.path LIKE ?', $categoryRow['path'] . '/%');
$this->_addFilter($storeId, 'is_active', 1);
$query = $this->_getWriteAdapter()->query($this->_select);
while ($row = $query->fetch()) {
$category = $this->_prepareCategory($row);
$categories[$category->getId()] = $category;
}
return $categories;
}
/**
* Prepare category
*
* @param array $categoryRow
* @return Varien_Object
*/
protected function _prepareCategory(array $categoryRow)
{
$category = new Varien_Object();
$category->setId($categoryRow[$this->getIdFieldName()]);
$categoryUrl = !empty($categoryRow['url']) ? $categoryRow['url'] : 'catalog/category/view/id/' . $category->getId();
$category->setUrl($categoryUrl);
return $category;
}
/**
* Add attribute to filter
*
* @param int $storeId
* @param string $attributeCode
* @param mixed $value
* @param string $type
* @return Zend_Db_Select
*/
protected function _addFilter($storeId, $attributeCode, $value, $type = '=')
{
if (!isset($this->_attributesCache[$attributeCode])) {
$attribute = Mage::getSingleton('catalog/category')->getResource()->getAttribute($attributeCode);
$this->_attributesCache[$attributeCode] = array(
'entity_type_id' => $attribute->getEntityTypeId(),
'attribute_id' => $attribute->getId(),
'table' => $attribute->getBackend()->getTable(),
'is_global' => $attribute->getIsGlobal(),
'backend_type' => $attribute->getBackendType()
);
}
$attribute = $this->_attributesCache[$attributeCode];
if (!$this->_select instanceof Zend_Db_Select) {
return false;
}
switch ($type) {
case '=':
$conditionRule = '=?';
break;
case 'in':
$conditionRule = ' IN(?)';
break;
default:
return false;
break;
}
if ($attribute['backend_type'] == 'static') {
$this->_select->where('e.' . $attributeCode . $conditionRule, $value);
} else {
$this->_select->join(
array('t1_'.$attributeCode => $attribute['table']),
'e.entity_id=t1_'.$attributeCode.'.entity_id AND t1_'.$attributeCode.'.store_id=0',
array()
)
->where('t1_'.$attributeCode.'.attribute_id=?', $attribute['attribute_id']);
if ($attribute['is_global']) {
$this->_select->where('t1_'.$attributeCode.'.value'.$conditionRule, $value);
} else {
$ifCase = $this->_select->getAdapter()->getCheckSql('t2_'.$attributeCode.'.value_id > 0', 't2_'.$attributeCode.'.value', 't1_'.$attributeCode.'.value');
$this->_select->joinLeft(
array('t2_'.$attributeCode => $attribute['table']),
$this->_getWriteAdapter()->quoteInto('t1_'.$attributeCode.'.entity_id = t2_'.$attributeCode.'.entity_id AND t1_'.$attributeCode.'.attribute_id = t2_'.$attributeCode.'.attribute_id AND t2_'.$attributeCode.'.store_id=?', $storeId),
array()
)
->where('('.$ifCase.')'.$conditionRule, $value);
}
}
return $this->_select;
}
}
Edit: Many thanks to Luke in his comment below! Here is what worked for me. I had to modify the code a bit since $category isn’t defined until after the if statement.
while ($row = $query->fetch()) {
// Added to exclude specific categories
if(in_array($this->_prepareCategory($row)->getId(), $this->ignoreCategories))
{
continue;
}
$category = $this->_prepareCategory($row);
$categories[$category->getId()] = $category;
}
I created the class property for the category IDs just as Luke had said:
protected $ignoreCategories = array("2","3","16");//Replace the numbers with your category IDs
For a quick solution add the code below, A much better way would be to add an attribute to the category EAV then use that for checking if it should be included in the sitemap output.
For the quick hack, add an array as a class property for the category IDs that should be ignored,
protected $ignoreCategories = array(“2″,”3″,”16”);
Then near the bottom of the getCollection() function check for these ID’s,
while ($row = $query->fetch()) {
}