6

Problem

I'm having a strange issue with my url_key field reverting to NULL on my catalog_category_flat_store_1 table following a reindex, but only on categories that I have created since enabling the Flat Category index.

As a result, when I attempt to fetch the category via url_key as so:

    $category = Mage::getModel('catalog/category')
        ->getCollection()
        ->addAttributeToFilter('url_key', 'my-url-key')
        ->getFirstItem();

    $category->load($category->getId());

I am unable to do so. If I go back and re-save the category, the url_key is added back to the flat table and I'm able to retrieve the category.

Has anyone else had this problem or am I missing something regarding the way flat tables operate?

What I've Found/Tried

Because the value would initially save and then disappear, I examined the catalog_category_entity files. Here's what I found:

  1. The url_key value is saving properly in catalog_category_entity_url_key
  2. However, neither the url_key nor the url_path attributes are saving in catalog_category_entity_varchar as they were with categories that I created before enabling Flat tables.
  3. If I manually add the url_key to catalog_category_entity_varchar, values are preserved and copied to catalog_category_flat_store_1 as expected when reindexing.

I have tried disabling the flat tables and while the url_key value is still not saved to catalog_category_entity_varchar, I am able to category via the url_key using my code above.

FWIW, I'm using Enterprise 1.13.

Update

I used MAGMI to import my products/categories; because CE uses varchar attributes rather than a separate table as the newer versions of enterprise do, this may be a non-issue. I created a fresh install of Enterprise and added the categories manually. I'm noticing that the url_key and url_path fields are not copied over to the flat tables anyway.

9

In Magento Enterprise 1.13 (or 1.12) url_key attribute was moved to its own table catalog_category_entiry_url_key (similarly product url_key attribute has its own table catalog_product_entiry_url_key). Also in 1.13 indexers were changed and are now run by the cronjob instead of manually. The problem is that indexer only takes values from catalog_category_entity_(varchar|int|decimal|text|datetime) and not catalog_category_entiry_url_key. Quick fix is to create a new module and rewrite enterprise_catalog/index_action_category_flat_refresh model with:

<enterprise_catalog>
    <rewrite>
        <index_action_category_flat_refresh>Mynamespace_Mymodule_Model_Refresh</index_action_category_flat_refresh>
    </rewrite>
</enterprise_catalog>

and in the class add url_key to $attributesType array

class Mynamespace_Mymodule_Model_Refresh extends Enterprise_Catalog_Model_Index_Action_Category_Flat_Refresh {

/**
 * Return attribute values for given entities and store
 *
 * @param array $entityIds
 * @param integer $storeId
 * @return array
 */
protected function _getAttributeValues($entityIds, $storeId) {
    if (!is_array($entityIds)) {
        $entityIds = array($entityIds);
    }
    $values = array();

    foreach ($entityIds as $entityId) {
        $values[$entityId] = array();
    }
    $attributes = $this->_getAttributes();
    $attributesType = array(
        'varchar',
        'int',
        'decimal',
        'text',
        'datetime',
        'url_key'   //add url_key to attributes type; otherwise url_key value will not be saved in the flat tables
                    //as it was moved to its own table in EE 1.13
    );
    foreach ($attributesType as $type) {
        foreach ($this->_getAttributeTypeValues($type, $entityIds, $storeId) as $row) {
            if (isset($row['entity_id']) && isset($row['attribute_id'])) {
                $attributeId = $row['attribute_id'];
                if (isset($attributes[$attributeId])) {
                    $attributeCode = $attributes[$attributeId]['attribute_code'];
                    $values[$row['entity_id']][$attributeCode] = $row['value'];
                }
            }
        }
    }
    return $values;
    }

}

This will add url_key to flat tables during reindex but it probably won't work with MAGMI import module.

4

Just in case anyone else runs into this - the URL Key and URL are no longer stored in the flat category table, hence the omitted value that confused me with the issue above when reindexing.

MAGMI adds these values to the catalog_category_entity_varchar table, as they are still used in the Community Edition.

Unfortunately, the loadByAttribute method doesn't work with url_key, so it appears to be a rather convoluted measure to fetch a category by url_key:

    $collection = Mage::getModel('catalog/category')
        ->getCollection();
        $collection->getSelect()
        ->join(
            array('url_keys' => 'catalog_category_entity_url_key'),
            'url_keys.entity_id = main_table.entity_id'
            )
        ->where('url_keys.value = ?', 'your-url-key');

    $category = $collection->getFirstItem();

    $category->load($category->getId());

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.