1

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

2
  • 1
    Did you check to see if any other module is rewriting Product.php? Sep 29, 2015 at 16:04
  • I just looked for "<catalog_resource>" in all the files of my project, and it finds only app/code/core/Mage/Catalog/etc/config.xml and app/code/local/Namespace/Module/etc/config.xml. I assume no other module rewrite this file then.
    – chris
    Sep 29, 2015 at 16:11

4 Answers 4

1

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.

6
  • I don't really understand why you want me to put <product>Namespace_Module_Model_Catalog_Resource_Product</product>, as the file to override is Mage_Catalog_Model_Resource_Product.
    – chris
    Sep 29, 2015 at 16:17
  • it will be ok as you mention in your post "<product>Namespace_Module_Model_Resource_Product</product>". I want you to try with class declaration. <class>Namespace_Module_Model</class> Sep 29, 2015 at 16:30
  • I did and it didn't work. My file names are also corrects (as you can see it in the code I've put into my initial post)
    – chris
    Sep 29, 2015 at 16:35
  • Ok. did you check any error in system.log or exception.log files ? Sep 29, 2015 at 16:44
  • Unfortunatelly, I don't have anything in my system.log or exception.log. The only thing which show up is a solar timeout which is totally irrelevant.
    – chris
    Sep 29, 2015 at 16:55
0

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);
}
6
  • I assume you wanted to write <resource_product>Namespace_Module_Catalog_Model_Resource_Product</resource_product> and you just forgot 'Model'. I've tried that but not working either.
    – chris
    Sep 29, 2015 at 16:57
  • Yes, that's what I wanted to write; I updated my comment :) Can you post the relevant section of the config.xml here?
    – Adi
    Sep 29, 2015 at 17:52
  • Like @R.S said, can you check if the product resource is overwritten by other modules, this time grepping the xml files for <resource_product>? /Edit: Alternatively, somewhere in a script do a $r = Mage::getResourceModel('catalog/product'); echo get_class($r) . PHP_EOL;
    – Adi
    Sep 29, 2015 at 17:56
  • I had also an extra Catalog in the path: Namespace_Module_Model_*Catalog*_Resource_Product; I updated my answer again.
    – Adi
    Sep 29, 2015 at 18:02
  • What do you mean by "in the path" ? an extra folder in your file system ? adding "Catalog" in the <resource_product> tag ?
    – chris
    Sep 30, 2015 at 8:48
0

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

3
  • Here is the output (which confirm nothing else is overriding those files): Mage_Core_Model_Config_Element Object ( [category] => Namespace_Module_Model_Resource_Category [product] => Namespace_Module_Model_Resource_Product )
    – chris
    Sep 30, 2015 at 8:45
  • @christophe It should work then now track by echo put echo "test from my module" before class class Namespace_Module_Model_Resource_Product at app/code/local/Namespace/Module/Model/Resource/Product.php Sep 30, 2015 at 8:53
  • I already have logs in both files but it still displays the logs in the core file. And I remove the var/cache folder everytime I do a change.
    – chris
    Sep 30, 2015 at 8:57
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.