2

Let's say I have custom EAV entity type with it's tables that have store field (just like catalog/product tables have). Can default EAV resource model save data per store? From what I have seen, in Mage_Eav_Model_Entity_Abstract there is _saveAttribute method (which is used for inserting and updating) which does not create store_id key:

protected function _saveAttribute($object, $attribute, $value)
{
    $table = $attribute->getBackend()->getTable();
    if (!isset($this->_attributeValuesToSave[$table])) {
        $this->_attributeValuesToSave[$table] = array();
    }

    $entityIdField = $attribute->getBackend()->getEntityIdField();

    $data   = array(
        'entity_type_id'    => $object->getEntityTypeId(),
        $entityIdField      => $object->getId(),
        'attribute_id'      => $attribute->getId(),
        'store_id'          => $object->getStoreId(),
        'value'             => $this->_prepareValueForSave($value, $attribute)
    );

    $this->_attributeValuesToSave[$table][] = $data;

    return $this;
}

I have also seen that products use different mechanism for this (in Mage_Catalog_Model_Resource_Abstract):

    protected function _saveAttributeValue($object, $attribute, $value)
{
    $write   = $this->_getWriteAdapter();
    $storeId = (int)Mage::app()->getStore($object->getStoreId())->getId();
    $table   = $attribute->getBackend()->getTable();

    /**
     * If we work in single store mode all values should be saved just
     * for default store id
     * In this case we clear all not default values
     */
    if (Mage::app()->isSingleStoreMode()) {
        $storeId = $this->getDefaultStoreId();
        $write->delete($table, array(
            'attribute_id = ?' => $attribute->getAttributeId(),
            'entity_id = ?'    => $object->getEntityId(),
            'store_id <> ?'    => $storeId
        ));
    }

    $data = new Varien_Object(array(
        'entity_type_id'    => $attribute->getEntityTypeId(),
        'attribute_id'      => $attribute->getAttributeId(),
        'store_id'          => $storeId,
        'entity_id'         => $object->getEntityId(),
        'value'             => $this->_prepareValueForSave($value, $attribute)
    ));
    $bind = $this->_prepareDataForTable($data, $table);

    if ($attribute->isScopeStore()) {
        /**
         * Update attribute value for store
         */
        $this->_attributeValuesToSave[$table][] = $bind;
    } else if ($attribute->isScopeWebsite() && $storeId != $this->getDefaultStoreId()) {
        /**
         * Update attribute value for website
         */
        $storeIds = Mage::app()->getStore($storeId)->getWebsite()->getStoreIds(true);
        foreach ($storeIds as $storeId) {
            $bind['store_id'] = (int)$storeId;
            $this->_attributeValuesToSave[$table][] = $bind;
        }
    } else {
        /**
         * Update global attribute value
         */
        $bind['store_id'] = $this->getDefaultStoreId();
        $this->_attributeValuesToSave[$table][] = $bind;
    }

    return $this;
}

This leads me to believe that it is impossible to make EAV based models with values per store without some overwriting. Since I have seen that people mention that it is possible to do it, I would like someone to clarify this for me.

2

It's possible.
When I create an EAV entity I make the entity model extend Mage_Catalog_Model_Abstract, the resource model extends Mage_Catalog_Model_Resource_Abstract, and the resource collection model extends Mage_Catalog_Model_Resource_Collection_Abstract.
This way the entity behaves in a similar was to the product or category entity.

You can give this module creator a try. It's not yet in a final stage but it should work for simple modules. It has support for creating EAV entities.

  • Yes I had that idea too. I just thought that that kind of approach might have some side effects when entities are not catalog related. – LDusan Apr 16 '14 at 12:27
  • @LDusan I don't thing it has side effects. Those classes I mentioned are never instantiated. They are just there as a common ancestor for the product and category classes. And, as you can see the product and category are 2 very different entities. It won't hurt if you add an other one :). – Marius Apr 16 '14 at 12:31
  • @Marius - one caveat I think is that, when adding attributes to those custom EAV entities, the catalog resource will insert into the catalog's specific additional tables. I don't think OP wants that. Looking at this article, I think you must declare your own tables in which your attribute would reside. – nevvermind Apr 17 '14 at 13:37
  • 1
    @nevvermind Until a few weeks ago I thought the same thing but based on the answers provided here magento.stackexchange.com/q/13598/146 it seams that is possible to store everything in the tables provided by Magento. – Marius Apr 17 '14 at 13:40
  • @Marius - Wow. So there's an EAV table fallback. And, yes, I was wrong actually: there's no additional table if you don't define it in eav_entity_type table. As for the attribute values, they seem to be going to eav_entity_int/decimal/... if you don't define your own. But I still don't like non-catalog EAV entities to use catalog resources. – nevvermind Apr 17 '14 at 13:58

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.