0

There seems to be a problem when saving different category URL keys for one category for different store views.

I have one website with one store with 2 store views. The first store view uses the default category url keys(from store 0). When I change the url key in the second store view, Magento sets the same request path attribute value for the child categories for the default store as for the 2nd store view. Example:

Url Keys:

+----------+----------------+--------------+----------+-----------+---------+
| value_id | entity_type_id | attribute_id | store_id | entity_id | value   |
+----------+----------------+--------------+----------+-----------+---------+
|   103466 |              3 |           35 |        0 |      3929 | dining  |
|   113116 |              3 |           35 |       19 |      3929 | dining2 |
+----------+----------------+--------------+----------+-----------+---------+


Request Path:
+----------+----------------+--------------+----------+-----------+--------------+
| value_id | entity_type_id | attribute_id | store_id | entity_id | value        |
+----------+----------------+--------------+----------+-----------+--------------+
|   103468 |              3 |           49 |        0 |      3929 | dining2.html |
|   113114 |              3 |           49 |       19 |      3929 | dining2.html |
+----------+----------------+--------------+----------+-----------+--------------+

I tracked it down to:

/**
     * Save category attribute
     *
     * @param Varien_Object $category
     * @param string $attributeCode
     * @return Mage_Catalog_Model_Resource_Url
     */
    public function saveCategoryAttribute(Varien_Object $category, $attributeCode)
    {
        $adapter = $this->_getWriteAdapter();
        if (!isset($this->_categoryAttributes[$attributeCode])) {
            $attribute = $this->getCategoryModel()->getResource()->getAttribute($attributeCode);

            $this->_categoryAttributes[$attributeCode] = array(
                'entity_type_id' => $attribute->getEntityTypeId(),
                'attribute_id'   => $attribute->getId(),
                'table'          => $attribute->getBackend()->getTable(),
                'is_global'      => $attribute->getIsGlobal()
            );
            unset($attribute);
        }

    $attributeTable = $this->_categoryAttributes[$attributeCode]['table'];

    $attributeData = array(
        'entity_type_id'    => $this->_categoryAttributes[$attributeCode]['entity_type_id'],
        'attribute_id'      => $this->_categoryAttributes[$attributeCode]['attribute_id'],
        'store_id'          => $category->getStoreId(),
        'entity_id'         => $category->getId(),
        'value'             => $category->getData($attributeCode)
    );

    if ($this->_categoryAttributes[$attributeCode]['is_global'] || $category->getStoreId() == 0) {
        $attributeData['store_id'] = 0;
    }

    $select = $adapter->select()
        ->from($attributeTable)
        ->where('entity_type_id = ?', (int)$attributeData['entity_type_id'])
        ->where('attribute_id = ?', (int)$attributeData['attribute_id'])
        ->where('store_id = ?', (int)$attributeData['store_id'])
        ->where('entity_id = ?', (int)$attributeData['entity_id']);

    $row = $adapter->fetchRow($select);
    $whereCond = array('value_id = ?' => $row['value_id']);
    if ($row) {
        $adapter->update($attributeTable, $attributeData, $whereCond);
    } else {
        $adapter->insert($attributeTable, $attributeData);
    }


    // <<<< BELOW it seems to add/update the value passed on store 0 >>>>>\\ 


    if ($attributeData['store_id'] != 0) {
        $attributeData['store_id'] = 0;
        $select = $adapter->select()
            ->from($attributeTable)
            ->where('entity_type_id = ?', (int)$attributeData['entity_type_id'])
            ->where('attribute_id = ?', (int)$attributeData['attribute_id'])
            ->where('store_id = ?', (int)$attributeData['store_id'])
            ->where('entity_id = ?', (int)$attributeData['entity_id']);

        $row = $adapter->fetchRow($select);
        if ($row) {
            $whereCond = array('value_id = ?' => $row['value_id']);
            $adapter->update($attributeTable, $attributeData, $whereCond);
        } else {
            $adapter->insert($attributeTable, $attributeData);
        }
    }
    unset($attributeData);

    return $this;
};

in Mage_Catalog_Model_Resource_Url Which is only called in Mage_Catalog_Model_Url::_refreshCategoryRewrites to update the url_key and url_path

Would anyone know why it does this, is there a reason you would want it to be added/updated to store 0 if you update a particular store.

  • Thanks for your reply, this seems to be base magento behaviour though, when looking at the code above. If you look under the bit where it says: // <<<< BELOW it seems to add/update the value passed on store 0 >>>>>\\ - you will see that it will update store 0 with the value passed even if it isn't intended for store 0. Thanks – Martijn Schot Sep 19 '14 at 21:56
  • - Create a store and store view. - Go to Catalog->Manage Categories - In "All Store Views" Scope create subcategory under root category for the store you created and set the url key. - Create new store view for same store - Go to Catalog->Manage Categories - From store view selector, select the new store view - Go to sub category and change the url key. - remember the id for this category in Mysql: select * from catalog_category_entity_varchar where attribute_id = (select attribute_id from eav_attribute where attribute_code = 'url_path' and entity_type_id = 3) and entity_id = $id; – Martijn Schot Sep 22 '14 at 7:38
0

Eventually found that the url indexer joins onto the default which means the default value is required

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.