Skip to content

Commit

Permalink
Add new functionality for blocking generating rewrites for disabled p…
Browse files Browse the repository at this point in the history
…roduct and category.

Add in config field create_url_for_disabled. When it is set as false dont generate redirects for disabled products and categories, what improves performance. Default is true, thanks to it it is compatible backwards.
  • Loading branch information
MarcinNowakMacopedia committed Jan 19, 2021
1 parent bfe9329 commit 9163a4d
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 26 deletions.
7 changes: 6 additions & 1 deletion app/code/core/Mage/Catalog/Model/Indexer/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ protected function _registerProductEvent(Mage_Index_Model_Event $event)
{
$product = $event->getDataObject();
$dataChange = $product->dataHasChangedFor('url_key')
|| $product->dataHasChangedFor('status')
|| $product->getIsChangedCategories()
|| $product->getIsChangedWebsites();

Expand All @@ -199,7 +200,11 @@ protected function _registerCategoryEvent(Mage_Index_Model_Event $event)
{
$category = $event->getDataObject();
if (!$category->getInitialSetupFlag() && $category->getLevel() > 1) {
if ($category->dataHasChangedFor('url_key') || $category->getIsChangedProductList()) {
if (
$category->dataHasChangedFor('url_key')
|| $category->getIsChangedProductList()
|| $category->dataHasChangedFor('is_active')
) {
$event->addNewData('rewrite_category_ids', array($category->getId()));
}
/**
Expand Down
201 changes: 182 additions & 19 deletions app/code/core/Mage/Catalog/Model/Resource/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,10 @@ protected function _prepareStoreRootCategories($stores)
* @param int|array $categoryIds
* @param int $storeId
* @param string $path
* @param bool $withDisabled
* @return array
*/
protected function _getCategories($categoryIds, $storeId = null, $path = null)
protected function _getCategories($categoryIds, $storeId = null, $path = null, $withDisabled = true)
{
$isActiveAttribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Category::ENTITY, 'is_active');
Expand Down Expand Up @@ -738,6 +739,10 @@ protected function _getCategories($categoryIds, $storeId = null, $path = null)
$rootCategoryPath = $this->getStores($storeId)->getRootCategoryPath();
$rootCategoryPathLength = strlen($rootCategoryPath);
}
if (!$withDisabled) {
$select->where('IF(c.value_id > 0, c.value, d.value) = 1');
}

$bind = array(
'attribute_id' => (int)$isActiveAttribute->getId(),
'store_id' => (int)$storeId
Expand Down Expand Up @@ -808,15 +813,16 @@ public function getCategory($categoryId, $storeId)
*
* @param int|array $categoryIds
* @param int $storeId
* @param bool $withDisabled
* @return Mage_Catalog_Model_Category[]|false
*/
public function getCategories($categoryIds, $storeId)
public function getCategories($categoryIds, $storeId, $withDisabled = true)
{
if (!$categoryIds || !$storeId) {
return false;
}

return $this->_getCategories($categoryIds, $storeId);
return $this->_getCategories($categoryIds, $storeId, null, $withDisabled);
}

/**
Expand Down Expand Up @@ -939,9 +945,11 @@ public function getProductIdsByCategory($category)
* @param int $storeId
* @param int $entityId
* @param int $lastEntityId
* @param bool $withDisabled
* @return array
* @throws Mage_Core_Model_Store_Exception
*/
protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId)
protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId, $withDisabled = true)
{
$products = array();
$websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
Expand Down Expand Up @@ -969,6 +977,16 @@ protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId
if ($productIds !== null) {
$select->where('e.entity_id IN(?)', $productIds);
}
if (!$withDisabled) {
$statusId = Mage::getResourceModel('eav/entity_attribute')
->getIdByCode('catalog_product', 'status');
$select->join(
['cpei' => 'catalog_product_entity_int'],
'cpei.entity_id = e.entity_id AND cpei.entity_type_id = 4 AND cpei.attribute_id = ' . (int)$statusId,
[]
);
$select->where('cpei.value <> 2');
}

$rowSet = $adapter->fetchAll($select, $bind);
foreach ($rowSet as $row) {
Expand Down Expand Up @@ -1013,12 +1031,14 @@ protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId
*
* @param int $productId
* @param int $storeId
* @param bool $withDisabled
* @return Varien_Object|false
* @throws Mage_Core_Model_Store_Exception
*/
public function getProduct($productId, $storeId)
public function getProduct($productId, $storeId, $withDisabled = true)
{
$entityId = 0;
$products = $this->_getProducts($productId, $storeId, 0, $entityId);
$products = $this->_getProducts($productId, $storeId, 0, $entityId, $withDisabled);
if (isset($products[$productId])) {
return $products[$productId];
}
Expand All @@ -1030,11 +1050,12 @@ public function getProduct($productId, $storeId)
*
* @param int $storeId
* @param int $lastEntityId
* @param bool $withDisabled
* @return Mage_Catalog_Model_Product[]
*/
public function getProductsByStore($storeId, &$lastEntityId)
public function getProductsByStore($storeId, &$lastEntityId, $withDisabled = true)
{
return $this->_getProducts(null, $storeId, $lastEntityId, $lastEntityId);
return $this->_getProducts(null, $storeId, $lastEntityId, $lastEntityId, $withDisabled);
}

/**
Expand All @@ -1054,32 +1075,87 @@ public function getProductsByCategory(Varien_Object $category, &$lastEntityId)
}

/**
* Find and remove unused products rewrites - a case when products were moved away from the category
* (either to other category or deleted), so rewrite "category_id-product_id" is invalid
* Unused function. Left for backward compatibility
*
* @param int $storeId
* @return $this
*/
public function clearCategoryProduct($storeId)
{
return $this->clearRewrites($storeId);
}

/**
* Find and remove unused rewrites a case when
* - products were moved away from the category (either to other category or deleted), so rewrite "category_id-product_id" is invalid
* - category
*
* @param int $storeId
* @return $this
*/
public function clearRewrites($storeId)
{
$adapter = $this->_getWriteAdapter();
list($select, $bind) = $this->getSelectToClearRewrites($adapter, $storeId);

$productUseCategories = Mage::getStoreConfigFlag('catalog/seo/product_use_categories');
$rewriteIds = $adapter->fetchCol($select, $bind);
if ($rewriteIds) {
$where = array($this->getIdFieldName() . ' IN(?)' => $rewriteIds);
$adapter->delete($this->getMainTable(), $where);
}

return $this;
}

/**
* Find and remove unused category rewrites - a case when category is disabled and in config field
* catalog/seo/create_url_for_disabled is set as false
*
* @param int $categoryId
* @param int|null $storeId
* @return $this
*/
public function clearDisabledCategory($categoryId, $storeId = null)
{
if (Mage::getStoreConfigFlag('catalog/seo/create_url_for_disabled')) {
return $this;
}

if (is_null($storeId)) {
foreach ($this->getStores() as $store) {
$this->clearDisabledCategory($categoryId, $store);
}
return $this;
}

$adapter = $this->_getWriteAdapter();

$table = $this->getTable(array('catalog/category', 'int'));
$select = $adapter->select()
->from(array('tur' => $this->getMainTable()), $this->getIdFieldName())
->joinLeft(
array('tcp' => $this->getTable('catalog/category_product')),
'tur.category_id = tcp.category_id AND tur.product_id = tcp.product_id',
array('ccei1' => $table),
'ccei1.attribute_id = :is_active_category_attribute_id AND ccei1.store_id = 0 AND ccei1.entity_id = tur.category_id',
array()
)
->joinLeft(
array('ccei2' => $table),
'ccei2.attribute_id = :is_active_category_attribute_id AND ccei2.store_id = :store_id AND ccei2.entity_id = tur.category_id',
array()
)
->where('IF(ccei2.value_id > 0, ccei2.value, ccei1.value) = 0')
->where('tur.store_id = :store_id')
->where('tur.category_id IS NOT NULL')
->where('tur.product_id IS NOT NULL');
->where('tur.category_id = :category_id');

if ($productUseCategories) {
$select->where('tcp.category_id IS NULL');
}
$rewriteIds = $adapter->fetchCol($select, array('store_id' => $storeId));
$isActiveCategoryAttribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Category::ENTITY, 'is_active');
$bind = [
'store_id' => $storeId,
'is_active_category_attribute_id' => $isActiveCategoryAttribute->getId(),
'category_id' => $categoryId
];

$rewriteIds = $adapter->fetchCol($select, $bind);
if ($rewriteIds) {
$where = array($this->getIdFieldName() . ' IN(?)' => $rewriteIds);
$adapter->delete($this->getMainTable(), $where);
Expand All @@ -1088,6 +1164,93 @@ public function clearCategoryProduct($storeId)
return $this;
}

/**
* Prepare select to find unused rewrites
* as set in configuration fields catalog/seo/product_use_categories and catalog/seo/create_url_for_disabled
*
* @param Magento_Db_Adapter_Pdo_Mysql $adapter
* @param int $storeId
* @return array
*/
protected function getSelectToClearRewrites($adapter, $storeId)
{
$productUseCategories = Mage::getStoreConfigFlag('catalog/seo/product_use_categories');
$createUrlForDisabled = Mage::getStoreConfigFlag('catalog/seo/create_url_for_disabled');

$bind = ['store_id' => $storeId];
$select = $adapter->select()
->from(array('tur' => $this->getMainTable()), $this->getIdFieldName())
->where('tur.store_id = :store_id')
->where('tur.is_system = 1');

if ($createUrlForDisabled) {

// Find rewrites for cartegory/product
$select->where('tur.category_id IS NOT NULL')
->where('tur.product_id IS NOT NULL');

// Find unused products rewrites - a case when products were moved away from the category
// (either to other category or deleted), so rewrite "category_id-product_id" is invalid
if ($productUseCategories) {
$select->joinLeft(
array('tcp' => $this->getTable('catalog/category_product')),
'tur.category_id = tcp.category_id AND tur.product_id = tcp.product_id',
array()
)
->where('tcp.category_id IS NULL');
}

} else {
// Find products, cartegories and cartegory/product rewrites for disabled products or cartegories
$productTable = $this->getTable(array('catalog/product', 'int'));
$categoryTable = $this->getTable(array('catalog/category', 'int'));
$select->joinLeft(
['cpei' => $productTable],
'cpei.entity_id = tur.product_id AND cpei.attribute_id = :product_status_attribute_id',
[]
)
->joinLeft(
array('ccei1' => $categoryTable),
'ccei1.attribute_id = :is_active_category_attribute_id AND ccei1.store_id = 0 AND ccei1.entity_id = tur.category_id',
array()
)
->joinLeft(
array('ccei2' => $categoryTable),
'ccei2.attribute_id = :is_active_category_attribute_id AND ccei2.store_id = :store_id AND ccei2.entity_id = tur.category_id',
array()
);
$productStatusAttributeId = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'status');
$bind['product_status_attribute_id'] = $productStatusAttributeId->getId();

$isActiveCategoryAttribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Category::ENTITY, 'is_active');
$bind['is_active_category_attribute_id'] = $isActiveCategoryAttribute->getId();

// product_is_disabled OR (category is disabled) OR (cartegory/product rewrite)
$where = '(cpei.value = 2 OR (IF(ccei2.value_id > 0, ccei2.value, ccei1.value) = 0) OR (tur.category_id IS NOT NULL AND tur.product_id IS NOT NULL) )';

// Find products, categories and cartegory/product rewrites for disabled products or categories
if ($productUseCategories) {
$select
->joinLeft(
array('tcp' => $this->getTable('catalog/category_product')),
'tcp.category_id = tur.category_id AND tcp.product_id = tur.product_id',
array()
);
// product_is_disabled OR (category is disabled) OR (cartegory/product rewrite AND product were moved away from the category)
$where ='(cpei.value = 2 OR (IF(ccei2.value_id > 0, ccei2.value, ccei1.value) = 0) OR (tur.category_id IS NOT NULL AND tur.product_id IS NOT NULL AND tcp.category_id IS NULL))';
}
$select->where($where);
}
$select->group('url_rewrite_id');

return [
$select,
$bind
];
}

/**
* Remove unused rewrites for product - called after we created all needed rewrites for product and know the categories
* where the product is contained ($excludeCategoryIds), so we can remove all invalid product rewrites that have other category ids
Expand Down
Loading

0 comments on commit 9163a4d

Please sign in to comment.