diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo.php
new file mode 100644
index 00000000000..b81d168917a
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo.php
@@ -0,0 +1,37 @@
+isValueChanged()) {
+ Mage::getModel('index/indexer')
+ ->getProcessByCode(Mage_Catalog_Helper_Category_Flat::CATALOG_CATEGORY_FLAT_PROCESS_CODE)
+ ->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
+
+ Mage::getModel('index/indexer')
+ ->getProcessByCode(Mage_Catalog_Helper_Product_Flat::CATALOG_FLAT_PROCESS_CODE)
+ ->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
+ }
+ return $this;
+ }
+}
diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo/Product.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo/Product.php
index fdc4c3b9fec..c7ddf64be58 100644
--- a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo/Product.php
+++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Seo/Product.php
@@ -20,12 +20,18 @@
class Mage_Adminhtml_Model_System_Config_Backend_Seo_Product extends Mage_Core_Model_Config_Data
{
/**
- * Refresh category url rewrites if configuration was changed
+ * Refresh products url rewrites if configuration was changed
*
* @return $this
*/
protected function _afterSave()
{
+ if ($this->isValueChanged()) {
+ Mage::getModel('index/indexer')
+ ->getProcessByCode(Mage_Catalog_Helper_Product_Flat::CATALOG_FLAT_PROCESS_CODE)
+ ->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
+ }
+
return $this;
}
}
diff --git a/app/code/core/Mage/Catalog/Model/Indexer/Url.php b/app/code/core/Mage/Catalog/Model/Indexer/Url.php
index a6f5b42bb67..757957001e2 100644
--- a/app/code/core/Mage/Catalog/Model/Indexer/Url.php
+++ b/app/code/core/Mage/Catalog/Model/Indexer/Url.php
@@ -40,7 +40,8 @@ class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
*/
protected $_matchedEntities = [
Mage_Catalog_Model_Product::ENTITY => [
- Mage_Index_Model_Event::TYPE_SAVE
+ Mage_Index_Model_Event::TYPE_SAVE,
+ Mage_Index_Model_Event::TYPE_MASS_ACTION
],
Mage_Catalog_Model_Category::ENTITY => [
Mage_Index_Model_Event::TYPE_SAVE
@@ -173,12 +174,36 @@ protected function _registerEvent(Mage_Index_Model_Event $event)
protected function _registerProductEvent(Mage_Index_Model_Event $event)
{
$product = $event->getDataObject();
- $dataChange = $product->dataHasChangedFor('url_key')
- || $product->getIsChangedCategories()
- || $product->getIsChangedWebsites();
+ $dataChange = false;
+ $products = [];
+
+ if ($product instanceof Mage_Catalog_Model_Product_Action) {
+ $attributesData = $product->getData('attributes_data');
+ $productsIds = $product->getData('product_ids');
+ $dataChange = isset($attributesData['status']) && isset($productsIds) && count($productsIds) > 0;
+ if ($dataChange) {
+ $products = Mage::getModel('catalog/product')->getCollection()
+ ->addFieldToFilter('entity_id', ['in'=> $productsIds]);
+ } else {
+ return;
+ }
+ }
+
+ if ($product instanceof Mage_Catalog_Model_Product) {
+ $dataChange =
+ (
+ $product->dataHasChangedFor('url_key')
+ || $product->dataHasChangedFor('status')
+ || $product->getIsChangedCategories()
+ || $product->getIsChangedWebsites()
+ ) && !$product->getExcludeUrlRewrite();
+ $products = [$product];
+ }
- if (!$product->getExcludeUrlRewrite() && $dataChange) {
- $event->addNewData('rewrite_product_ids', [$product->getId()]);
+ if ($dataChange) {
+ foreach ($products as $product) {
+ $event->addNewData('rewrite_product_ids', [$product->getId()]);
+ }
}
}
@@ -191,7 +216,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', [$category->getId()]);
}
/**
diff --git a/app/code/core/Mage/Catalog/Model/Resource/Url.php b/app/code/core/Mage/Catalog/Model/Resource/Url.php
index 6e15bccce99..63c092eed84 100644
--- a/app/code/core/Mage/Catalog/Model/Resource/Url.php
+++ b/app/code/core/Mage/Catalog/Model/Resource/Url.php
@@ -56,6 +56,16 @@ class Mage_Catalog_Model_Resource_Url extends Mage_Core_Model_Resource_Db_Abstra
*/
protected $_rootChildrenIds = [];
+ /**
+ * @var int
+ */
+ protected $_productEntityTypeId;
+
+ /**
+ * @var int
+ */
+ protected $_statusAttributeId;
+
/**
* Load core Url rewrite model
*
@@ -63,6 +73,9 @@ class Mage_Catalog_Model_Resource_Url extends Mage_Core_Model_Resource_Db_Abstra
protected function _construct()
{
$this->_init('core/url_rewrite', 'url_rewrite_id');
+ $this->_productEntityTypeId = Mage::getSingleton('eav/config')->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getId();
+ $this->_statusAttributeId = Mage::getModel('catalog/resource_eav_attribute')
+ ->loadByCode($this->_productEntityTypeId, 'status')->getId();
}
/**
@@ -678,9 +691,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');
@@ -728,6 +742,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 = [
'attribute_id' => (int)$isActiveAttribute->getId(),
'store_id' => (int)$storeId
@@ -796,15 +814,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);
}
/**
@@ -927,9 +946,10 @@ public function getProductIdsByCategory($category)
* @param int $storeId
* @param int $entityId
* @param int $lastEntityId
+ * @param bool $withDisabled
* @return array
*/
- protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId)
+ protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId, $withDisabled = true)
{
$products = [];
$websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
@@ -957,6 +977,14 @@ protected function _getProducts($productIds, $storeId, $entityId, &$lastEntityId
if ($productIds !== null) {
$select->where('e.entity_id IN(?)', $productIds);
}
+ if (!$withDisabled) {
+ $select->join(
+ ['cpei' => 'catalog_product_entity_int'],
+ 'cpei.entity_id = e.entity_id AND cpei.entity_type_id = ' . $this->_productEntityTypeId . ' AND cpei.attribute_id = ' . $this->_statusAttributeId,
+ []
+ );
+ $select->where('cpei.value <> ' . Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
+ }
$rowSet = $adapter->fetchAll($select, $bind);
foreach ($rowSet as $row) {
@@ -1001,9 +1029,11 @@ 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);
@@ -1015,11 +1045,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);
}
/**
@@ -1028,6 +1059,7 @@ public function getProductsByStore($storeId, &$lastEntityId)
* @param Varien_Object $category
* @param int $lastEntityId
* @return array
+ * @throws Mage_Core_Model_Store_Exception
*/
public function getProductsByCategory(Varien_Object $category, &$lastEntityId)
{
@@ -1039,27 +1071,93 @@ 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
+ * @deprecated
*/
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);
+
+ $rewriteIds = $adapter->fetchCol($select, $bind);
+ if ($rewriteIds) {
+ $where = [$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|Mage_Core_Model_Store|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;
+ }
+ if ($storeId instanceof Mage_Core_Model_Store) {
+ $storeId = $storeId->getStoreId();
+ } elseif (!is_int($storeId)) {
+ throw new Exception('StoreId must by int or Mage_Core_Model_Store');
+ }
+
+ $adapter = $this->_getWriteAdapter();
+
+ $table = $this->getTable(['catalog/category', 'int']);
$select = $adapter->select()
->from(['tur' => $this->getMainTable()], $this->getIdFieldName())
->joinLeft(
- ['tcp' => $this->getTable('catalog/category_product')],
- 'tur.category_id = tcp.category_id AND tur.product_id = tcp.product_id',
+ ['ccei1' => $table],
+ 'ccei1.attribute_id = :is_active_category_attribute_id AND ccei1.store_id = 0 AND ccei1.entity_id = tur.category_id',
[]
)
+ ->joinLeft(
+ ['ccei2' => $table],
+ 'ccei2.attribute_id = :is_active_category_attribute_id AND ccei2.store_id = :store_id AND ccei2.entity_id = tur.category_id',
+ []
+ )
+ ->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('tcp.category_id IS NULL');
- $rewriteIds = $adapter->fetchCol($select, ['store_id' => $storeId]);
+ ->where('tur.category_id = :category_id');
+
+ $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 = [$this->getIdFieldName() . ' IN(?)' => $rewriteIds];
$adapter->delete($this->getMainTable(), $where);
@@ -1068,6 +1166,91 @@ 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(['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(
+ ['tcp' => $this->getTable('catalog/category_product')],
+ 'tur.category_id = tcp.category_id AND tur.product_id = tcp.product_id',
+ []
+ )
+ ->where('tcp.category_id IS NULL');
+ }
+ } else {
+ // Find products, cartegories and cartegory/product rewrites for disabled products or cartegories
+ $productTable = $this->getTable(['catalog/product', 'int']);
+ $categoryTable = $this->getTable(['catalog/category', 'int']);
+ $select->joinLeft(
+ ['cpei' => $productTable],
+ 'cpei.entity_id = tur.product_id AND cpei.attribute_id = :product_status_attribute_id',
+ []
+ )
+ ->joinLeft(
+ ['ccei1' => $categoryTable],
+ 'ccei1.attribute_id = :is_active_category_attribute_id AND ccei1.store_id = 0 AND ccei1.entity_id = tur.category_id',
+ []
+ )
+ ->joinLeft(
+ ['ccei2' => $categoryTable],
+ 'ccei2.attribute_id = :is_active_category_attribute_id AND ccei2.store_id = :store_id AND ccei2.entity_id = tur.category_id',
+ []
+ );
+ $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(
+ ['tcp' => $this->getTable('catalog/category_product')],
+ 'tcp.category_id = tur.category_id AND tcp.product_id = tur.product_id',
+ []
+ );
+ // 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
diff --git a/app/code/core/Mage/Catalog/Model/Url.php b/app/code/core/Mage/Catalog/Model/Url.php
index e68b3ee259b..6911ca21f6b 100644
--- a/app/code/core/Mage/Catalog/Model/Url.php
+++ b/app/code/core/Mage/Catalog/Model/Url.php
@@ -36,6 +36,9 @@ class Mage_Catalog_Model_Url
*/
public const ALLOWED_REQUEST_PATH_OVERFLOW = 10;
+ public const XML_PATH_PRODUCT_USE_CATEGORIES = 'catalog/seo/product_use_categories';
+ public const XML_PATH_CREATE_URL_FOR_DISABLED = 'catalog/seo/create_url_for_disabled';
+
/**
* Resource model
*
@@ -71,20 +74,6 @@ class Mage_Catalog_Model_Url
*/
protected $_rewrite;
- /**
- * Cache for product rewrite suffix
- *
- * @var array
- */
- protected $_productUrlSuffix = [];
-
- /**
- * Cache for category rewrite suffix
- *
- * @var array
- */
- protected $_categoryUrlSuffix = [];
-
/**
* Flag to overwrite config settings for Catalog URL rewrites history maintainance
*
@@ -238,7 +227,7 @@ public function refreshRewrites($storeId = null)
$this->clearStoreInvalidRewrites($storeId);
$this->refreshCategoryRewrite($this->getStores($storeId)->getRootCategoryId(), $storeId, false);
$this->refreshProductRewrites($storeId);
- $this->getResource()->clearCategoryProduct($storeId);
+ $this->getResource()->clearRewrites($storeId);
return $this;
}
@@ -364,7 +353,7 @@ protected function _refreshProductRewrite(Varien_Object $product, Varien_Object
}
/**
- * Refresh products for catwgory
+ * Refresh products for category
*
* @param Varien_Object|Mage_Catalog_Model_Category $category
* @return $this
@@ -375,7 +364,7 @@ protected function _refreshCategoryProductRewrites(Varien_Object $category)
$process = true;
$lastEntityId = 0;
$firstIteration = true;
- while ($process == true) {
+ while ($process === true) {
$products = $this->getResource()->getProductsByCategory($category, $lastEntityId);
if (!$products) {
if ($firstIteration) {
@@ -419,19 +408,28 @@ protected function _refreshCategoryProductRewrites(Varien_Object $category)
* @param bool $refreshProducts
* @return $this
*/
- public function refreshCategoryRewrite($categoryId, $storeId = null, $refreshProducts = true)
+ public function refreshCategoryRewrite($categoryId, $storeId = null, $refreshProducts = null)
{
if (is_null($storeId)) {
foreach ($this->getStores() as $store) {
- $this->refreshCategoryRewrite($categoryId, $store->getId(), $refreshProducts);
+ $this->refreshCategoryRewrite($categoryId, $store->getId());
}
return $this;
}
+ if (is_null($refreshProducts)) {
+ $refreshProducts = Mage::getStoreConfigFlag(self::XML_PATH_PRODUCT_USE_CATEGORIES, $storeId);
+ }
$category = $this->getResource()->getCategory($categoryId, $storeId);
if (!$category) {
return $this;
}
+ $createForDisabled = Mage::getStoreConfigFlag(self::XML_PATH_CREATE_URL_FOR_DISABLED, $storeId);
+
+ if (!$createForDisabled && !$category->getIsActive()) {
+ $this->getResource()->clearDisabledCategory($category->getId());
+ return $this;
+ }
// Load all childs and refresh all categories
$category = $this->getResource()->loadCategoryChilds($category);
@@ -466,35 +464,41 @@ public function refreshProductRewrite($productId, $storeId = null)
}
$product = $this->getResource()->getProduct($productId, $storeId);
- if ($product) {
- $store = $this->getStores($storeId);
- $storeRootCategoryId = $store->getRootCategoryId();
+ if (!$product) {
+ // Product doesn't belong to this store - clear all its url rewrites including root one
+ $this->getResource()->clearProductRewrites($productId, $storeId, []);
+ return $this;
+ }
+ $store = $this->getStores($storeId);
+ $storeRootCategoryId = $store->getRootCategoryId();
+
+ $this->_rewrites = $this->getResource()->prepareRewrites($storeId, '', $productId);
+
+ $categories = [];
+ if (Mage::getStoreConfigFlag(self::XML_PATH_PRODUCT_USE_CATEGORIES, $storeId)) {
// List of categories the product is assigned to, filtered by being within the store's categories root
$categories = $this->getResource()->getCategories($product->getCategoryIds(), $storeId);
- $this->_rewrites = $this->getResource()->prepareRewrites($storeId, '', $productId);
+ }
- // Add rewrites for all needed categories
- // If product is assigned to any of store's categories -
- // we also should use store root category to create root product url rewrite
- if (!isset($categories[$storeRootCategoryId])) {
- $categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
- }
+ // Add rewrites for all needed categories
+ // If product is assigned to any of store's categories -
+ // we also should use store root category to create root product url rewrite
+ if (!isset($categories[$storeRootCategoryId])) {
+ $categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
+ }
- // Create product url rewrites
- foreach ($categories as $category) {
- $this->_refreshProductRewrite($product, $category);
- }
+ // Create product url rewrites
+ foreach ($categories as $category) {
+ $this->_refreshProductRewrite($product, $category);
+ }
- // Remove all other product rewrites created earlier for this store - they're invalid now
- $excludeCategoryIds = array_keys($categories);
- $this->getResource()->clearProductRewrites($productId, $storeId, $excludeCategoryIds);
+ // Remove all other product rewrites created earlier for this store - they're invalid now
+ $excludeCategoryIds = array_keys($categories);
- unset($categories);
- unset($product);
- } else {
- // Product doesn't belong to this store - clear all its url rewrites including root one
- $this->getResource()->clearProductRewrites($productId, $storeId, []);
+ // Product is disabled and in configuration set to not create for disabled - clear all its url rewrites including root one
+ if ($product->getStatus() === Mage_Catalog_Model_Product_Status::STATUS_DISABLED) {
+ $excludeCategoryIds = [];
}
return $this;
@@ -512,36 +516,42 @@ public function refreshProductRewrites($storeId)
$storeRootCategoryId = $this->getStores($storeId)->getRootCategoryId();
$storeRootCategoryPath = $this->getStores($storeId)->getRootCategoryPath();
$this->_categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
+ $productUseCategories = Mage::getStoreConfigFlag(self::XML_PATH_PRODUCT_USE_CATEGORIES, $storeId);
+ $createForDisabled = Mage::getStoreConfigFlag(self::XML_PATH_CREATE_URL_FOR_DISABLED, $storeId);
$lastEntityId = 0;
- $process = true;
- while ($process == true) {
- $products = $this->getResource()->getProductsByStore($storeId, $lastEntityId);
+ while (true) {
+ $products = $this->getResource()->getProductsByStore($storeId, $lastEntityId, $createForDisabled);
+
if (!$products) {
- $process = false;
break;
}
$this->_rewrites = $this->getResource()->prepareRewrites($storeId, false, array_keys($products));
$loadCategories = [];
- foreach ($products as $product) {
- foreach ($product->getCategoryIds() as $categoryId) {
- if (!isset($this->_categories[$categoryId])) {
- $loadCategories[$categoryId] = $categoryId;
+
+ if ($productUseCategories) {
+ foreach ($products as $product) {
+ foreach ($product->getCategoryIds() as $categoryId) {
+ if (!isset($this->_categories[$categoryId])) {
+ $loadCategories[$categoryId] = $categoryId;
+ }
}
}
}
if ($loadCategories) {
- foreach ($this->getResource()->getCategories($loadCategories, $storeId) as $category) {
+ foreach ($this->getResource()->getCategories($loadCategories, $storeId, $createForDisabled) as $category) {
$this->_categories[$category->getId()] = $category;
}
}
+ }
- foreach ($products as $product) {
- $this->_refreshProductRewrite($product, $this->_categories[$storeRootCategoryId]);
+ foreach ($products as $product) {
+ $this->_refreshProductRewrite($product, $this->_categories[$storeRootCategoryId]);
+ if ($productUseCategories) {
foreach ($product->getCategoryIds() as $categoryId) {
if ($categoryId != $storeRootCategoryId && isset($this->_categories[$categoryId])) {
if (strpos($this->_categories[$categoryId]['path'], $storeRootCategoryPath . '/') !== 0) {
@@ -574,6 +584,7 @@ public function clearStoreInvalidRewrites($storeId = null)
}
return $this;
}
+ $createForDisabled = Mage::getStoreConfigFlag(self::XML_PATH_CREATE_URL_FOR_DISABLED, $storeId);
$this->getResource()->clearStoreInvalidRewrites($storeId);
return $this;
@@ -974,6 +985,7 @@ protected function _saveRewriteHistory($rewriteData, $rewrite)
$rewriteData['options'] = 'RP'; // Redirect = Permanent
$this->getResource()->saveRewriteHistory($rewriteData);
}
+ $this->getResource()->clearProductRewrites($productId, $storeId);
return $this;
}
diff --git a/app/code/core/Mage/Catalog/etc/config.xml b/app/code/core/Mage/Catalog/etc/config.xml
index 61cfb611821..fb292685d90 100644
--- a/app/code/core/Mage/Catalog/etc/config.xml
+++ b/app/code/core/Mage/Catalog/etc/config.xml
@@ -803,6 +803,7 @@
.html
.html
1
+ 1
1
-
0
diff --git a/app/code/core/Mage/Catalog/etc/system.xml b/app/code/core/Mage/Catalog/etc/system.xml
index 3b099086c8b..1888e50ddda 100644
--- a/app/code/core/Mage/Catalog/etc/system.xml
+++ b/app/code/core/Mage/Catalog/etc/system.xml
@@ -265,6 +265,16 @@
1
1
+
+
+ select
+ adminhtml/system_config_source_yesno
+ adminhtml/system_config_backend_seo
+ 4
+ 1
+ 1
+ 1
+
select
diff --git a/phpstan.dist.baseline.neon b/phpstan.dist.baseline.neon
index 8a1e7f903af..188d240e82e 100644
--- a/phpstan.dist.baseline.neon
+++ b/phpstan.dist.baseline.neon
@@ -1915,16 +1915,6 @@ parameters:
count: 1
path: app/code/core/Mage/Catalog/Model/Resource/Product/Link/Product/Collection.php
- -
- message: "#^Variable \\$category might not be defined\\.$#"
- count: 1
- path: app/code/core/Mage/Catalog/Model/Resource/Url.php
-
- -
- message: "#^Loose comparison using \\=\\= between true and true will always evaluate to true\\.$#"
- count: 2
- path: app/code/core/Mage/Catalog/Model/Url.php
-
-
message: "#^Property Mage_Catalog_Model_Url\\:\\:\\$_saveRewritesHistory \\(bool\\) on left side of \\?\\? is not nullable\\.$#"
count: 1