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

  • 1
    Did you check to see if any other module is rewriting Product.php? – Renon Stewart Sep 29 '15 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. – christophe Sep 29 '15 at 16:11
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.

  • 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. – christophe Sep 29 '15 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> – Akhilesh Patel Sep 29 '15 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) – christophe Sep 29 '15 at 16:35
  • Ok. did you check any error in system.log or exception.log files ? – Akhilesh Patel Sep 29 '15 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. – christophe Sep 29 '15 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);
}
  • 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. – christophe Sep 29 '15 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 '15 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 '15 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 '15 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 ? – christophe Sep 30 '15 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

  • 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 ) – christophe Sep 30 '15 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 – Minesh Patel Sep 30 '15 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. – christophe Sep 30 '15 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, privacy policy and cookie policy

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