Question

I'm trying to override the class Mage_Catalog_Model_Resource_Product but it always use the core file. Could you please tell me what's wrong ? Thanks

app/code/local/Namespace/Module/etc/config.xml:

<config>
    [...]
    <global>
        [...]
        <models>
          <catalog>
              <rewrite>
                  <config>Namespace_Module_Model_Config</config>
                  <category>Namespace_Module_Model_Category</category>
                  <layer>Namespace_Module_Model_Layer</layer>
              </rewrite>
          </catalog>
          <catalog_resource>
              <rewrite>
                  <category>Namespace_Module_Model_Resource_Category</category>
                  <product>Namespace_Module_Model_Resource_Product</product>
              </rewrite>
          </catalog_resource>
       </models>
    </global>
    [...]
</config>

app/code/local/Namespace/Module/Model/Resource/Product.php:

<?php
class Namespace_Module_Model_Resource_Product extends Mage_Catalog_Model_Resource_Product
{
    protected function _saveCategories(Varien_Object $object)
    {    
        /**
         * If category ids data is not declared we haven't do manipulations
         */
        if (!$object->hasCategoryIds()) {
            return $this;
        }
        $categoryIds = $object->getCategoryIds();
        $oldCategoryIds = $this->getCategoryIds($object);

        $object->setIsChangedCategories(false);

        $insert = array_diff($categoryIds, $oldCategoryIds);
        $delete = array_diff($oldCategoryIds, $categoryIds);

        $write = $this->_getWriteAdapter();
        if (!empty($insert)) {
            $data = array();
            foreach ($insert as $categoryId) {
                if (empty($categoryId)) {
                    continue;
                }
                $data[] = array(
                    'category_id' => (int)$categoryId,
                    'product_id'  => (int)$object->getId(),
                    'position'    => 500  // HERE'S WHAT I WANT TO CUSTOMIZE
                );
            }
            if ($data) {                   
                $write->insertMultiple($this->_productCategoryTable, $data);
            }
        }

        if (!empty($delete)) {
            foreach ($delete as $categoryId) {
                $where = array(
                    'product_id = ?'  => (int)$object->getId(),
                    'category_id = ?' => (int)$categoryId,
                );

                $write->delete($this->_productCategoryTable, $where);
            }
        }

        if (!empty($insert) || !empty($delete)) {
            $object->setAffectedCategoryIds(array_merge($insert, $delete));
            $object->setIsChangedCategories(true);
        }

        return $this;
    }
}

And I've also override the Model_Resource_Category, but this one is correctly working ! For reference:

app/code/local/Namespace/Module/Model/Resource/Category.php:

<?php
class Namespace_Module_Model_Resource_Category extends Mage_Catalog_Model_Resource_Category
{
    protected function _saveCategoryProducts($category)
    {
        $category->setIsChangedProductList(false);
        $id = $category->getId();
        /**
         * new category-product relationships
         */
        $products = $category->getPostedProducts();

        /**
         * Example re-save category
         */
        if ($products === null) {
            return $this;
        }

        /**
         * old category-product relationships
         */
        $oldProducts = $category->getProductsPosition();

        $insert = array_diff_key($products, $oldProducts);
        $delete = array_diff_key($oldProducts, $products);

        /**
         * Find product ids which are presented in both arrays
         * and saved before (check $oldProducts array)
         */
        $update = array_intersect_key($products, $oldProducts);
        $update = array_diff_assoc($update, $oldProducts);

        $adapter = $this->_getWriteAdapter();

        /**
         * Delete products from category
         */
        if (!empty($delete)) {
            $cond = array(
                'product_id IN(?)' => array_keys($delete),
                'category_id=?' => $id
            );
            $adapter->delete($this->_categoryProductTable, $cond);
        }

        /**
         * Add products to category
         */
        if (!empty($insert)) {
            $data = array();
            foreach ($insert as $productId => $position) {
                $data[] = array(
                    'category_id' => (int)$id,
                    'product_id'  => (int)$productId,
                    'position'    => empty($position)?500:(int)$position
                );
            }
            $adapter->insertMultiple($this->_categoryProductTable, $data);
        }

        /**
         * Update product positions in category
         */
        if (!empty($update)) {
            foreach ($update as $productId => $position) {
                $where = array(
                    'category_id = ?'=> (int)$id,
                    'product_id = ?' => (int)$productId
                );
                $bind  = array('position' => empty($position)?500:(int)$position);
                $adapter->update($this->_categoryProductTable, $bind, $where);
            }
        }

        if (!empty($insert) || !empty($delete)) {
            $productIds = array_unique(array_merge(array_keys($insert), array_keys($delete)));
            Mage::dispatchEvent('catalog_category_change_products', array(
                'category'      => $category,
                'product_ids'   => $productIds
            ));
        }

        if (!empty($insert) || !empty($update) || !empty($delete)) {
            $category->setIsChangedProductList(true);

            /**
             * Setting affected products to category for third party engine index refresh
             */
            $productIds = array_keys($insert + $delete + $update);
            $category->setAffectedProductIds($productIds);
        }
        return $this;
    }
}

Any idea why it is working with Model/Resource/Category.php and not Model/Resource/Product.php ?

EDIT: Here's my module declaration (just in case) where I declare the core Catalog module as a dependency.

app/etc/Namespace_Module.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <Namespace_Module>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Catalog/>
                <Unirgy_DropshipMicrosite/>
            </depends>
        </Namespace_Module>
    </modules>
</config>

Thanks

Was it helpful?

Solution 4

Finally, after a few more investigations, it appears that it is another class which is used from the Unirgy Dropship plugin.

I don't have the whole picture, but I had to override the class app/code/community/Unirgy/DropshipVendorProduct/Model/Mysql4/Product.php which extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product which extends Mage_Catalog_Model_Resource_Product.

It is really tricky but in the end, overriding this file was the solution.

OTHER TIPS

Try this way. Make sure your Product.php file is exist in correct folder structure.

        <models>
            <module>
                <class>Namespace_Module_Model</class>
            </module>
            <catalog_resource>
                <rewrite>
                    <product>Namespace_Module_Model_Catalog_Resource_Product</product>
                </rewrite>
            </catalog_resource>
        </models>

Also check you have written your class name correct.

Try:

...
<models>
    <catalog>
        <rewrite>
            <resource_product>Namespace_Module_Model_Resource_Product</resource_product>
        </rewrite>
    </catalog>
</models>
...

It's a bit miss-leading, but a resource model is... well.. a model :)

/Edit: You can see how resources are loaded in the Mage class in app/Mage.php, getResourceModel method which eventually calls Mage_Core_Model_Config::getResourceModelInstance bellow:

public function getResourceModelInstance($modelClass='', $constructArguments=array())
{
    $factoryName = $this->_getResourceModelFactoryClassName($modelClass);
    if (!$factoryName) {
        return false;
    }
    return $this->getModelInstance($factoryName, $constructArguments);
}

Your rewrite code seems correct try to check other module is rewriting this model ?

Create one test file on root of magento copy below code in that and run

    require_once("app/Mage.php");
    Mage::app();
    echo "<pre>";
    print_r(Mage::getConfig()->getNode('global/models/catalog_resource/rewrite'));

You will get list of rewrite for catalog_resource

Hope this will help

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top