How to override a camelCased model file in Magento? - magento

I have a shipping community model that has a camel cased class/file witch I would like to override.
The original file/class is located under app/code/community/PedroTeixeira/Correios/Model/Carrier/CorreiosMethod.php and I would like to override a method of this file, or the whole class under app/code/local/Esmart/CorreiosImprovements/Model/Carrier/CorreiosMethod.php.
In the original module config file, I can see it's model declaration in config.xml as follows:
<global>
...
<models>
<pedroteixeira_correios>
<class>PedroTeixeira_Correios_Model</class>
</pedroteixeira_correios>
</models>
...
<sales>
<shipping>
<carriers>
<pedroteixeira_correios>
<class>PedroTeixeira_Correios_Model_Carrier_CorreiosMethod</class>
</pedroteixeira_correios>
</carriers>
</shipping>
</sales>
</global>
At my module config.xml I've declared the override this way:
<global>
<models>
<esmart_correiosimprovements>
<class>Esmart_CorreiosImprovements_Model</class>
</esmart_correiosimprovements>
<pedroteixeira_correios>
<rewrite>
<carrier_correiosMethod>Esmart_CorreiosImprovements_Model_Carrier_CorreiosMethod</carrier_correiosMethod>
</rewrite>
</pedroteixeira_correios>
</models>
</global>
Usually the model file isn't camel cased, so I guess it's easier. Or am I missing something here?
Any help is appreciated.

The class group (<pedroteixeira_correios>) to use in your rewrite syntax depends on the class group declaration in the module's config.
The class ID (<carrier_correiosMethod>) to use in your rewrite syntax depends entirely on how the class is invoked in the code. For your example, the following would all instantiate the original class instance on case-sensitive filesystems:
pedroteixeira_correios/carrier_correiosMethod
pedroteixeira_correios/Carrier_correiosMethod
pedroteixeira_correios/carrier_CorreiosMethod
pedroteixeira_correios/Carrier_CorreiosMethod
On case-insensitive filesystems, any combination of casing for the class ID part would yield the model instance. Hopefully the extension vendor followed a consistent pattern when specifying their class in code/markup, but you can specify multiple xpaths using the list above to handle all permutations.

Related

overriding class first to second working but overriding second to third not working

I am overriding AW_Blog_Block_Cat and it is working good.
<global>
<blocks>
<blog>
<rewrite>
<cat>King_Ring_Block_Updates_Cat</cat>
</rewrite>
</blog>
</blocks>
</global>
Now I want to override the above class King_Ring_Block_Updates_Cat in other module and it's not overriding. Still showing the above class(King_Ring_Block_Updates_Cat), not showing the below one(Cat_Rat_Block_Updates_Bat). Can anyone please tell me why is that?
config is:
<global>
<blocks>
<ring>
<rewrite>
<updates_cat>Cat_Rat_Block_Updates_Bat</updates_cat>
</rewrite>
</ring>
</blocks>
</global>
Class definition
Cat_Rat_Block_Updates_Bat extends King_Ring_Block_Updates_Cat
Check your XML for second rewrite.
You are starting the module name as <ring> and ending it with </blog> instead of ring itself.
Another issue, you are starting the tag <updates_cat>, and ending it with </cat>.
Do you want developers here to parse your XML and check your typos?
Check your code thoroughly before posting things here.
Change the required things as I said, clear cache, and it should work.
I found it in the end. Nothing was wrong with the configuration or paths.
It was In my Layout.xml, as I was kept on calling the wrong block type to override. I was kept on calling the same parent block type which had already been overridden by second block, that is why it never rendered.
Now in order to override the second block I specify that block type and obviously it works!!
<block type="rat/updates_bat" name="N" template="whatever temp"/>.

Core overrides in Magento

So I found an answer for a question I had about dynamic option pricing, but that lead to me being stumped. I can understand the majority of the answer, but when it comes to the XML and module implementation, I'm lost.
Here's what I'm trying to do:
http://www.magentocommerce.com/boards/viewthread/260544/#t348802
Need to override the Mage_Catalog_Model_Product_Type_Price model and the Mage_Catalog_Block_Product_View_Options block.
Modified Price.php is located at
/app/core/local/rtega/dynamicPrice/Model/Product/Type/Price.php
Modified Options.php is located at
/app/core/local/rtega/dynamicPrice/Block/Product/View/Options.php
Have rtega_dynamicPrice.xml in
/app/etc/modules/
Below is current config.xml located in
/app/core/local/rtega/dynamicPrice/etc/
<?xml version="1.0"?>
<config>
<modules>
<rtega_dynamicPrice>
<version>1.0.0</version>
</rtega_dynamicPrice>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<product_view_options>rtega_dynamicPrice_Block_Product_View_Options</product_view_options>
</rewrite>
</catalog>
</blocks>
<catalog>
<product>
<type>
<configurable>
<price_model>rtega_dynamicPrice_Model_Product_Type_Price</price>
</configurable>
</type>
</product>
</catalog>
</global>
</config>
Any help is greatly appreciated!
Three things to mention.
Firstly, I don't know how well Magento will handle your casing of "rtega" and "dynamicPrice". This might cause an issue either now or in the future. My recommended casing would be "Rtega" and "Dynamicprice". But it might be fine.
Secondly, your block rewrite xml looks fine, but the rewrite for the catalog Model is incorrect. I'd expect to see:
<config>
...
<global>
...
<models>
<catalog>
<rewrite>
<product_type_price>rtega_dynamicPrice_Model_Product_Type_Price</product_type_price>
</rewrite>
</catalog>
</models>
...
</global>
...
</config>
The best way to think about this is to break it down to how you instantiate the original model in the first place. In this case, we would call
Mage::getModel("catalog/product_type_price");
so the first xml node is "models", since this is a model, the next xml node is the portion before the slash (catalog), then add a rewrite tag, then after the slash becomes the next xml node, like so:
<models>
<catalog>
<rewrite>
<product_type_price>
Thirdly, in this instance it's important to see the files that you've mentioned are at:
/app/core/local/rtega/dynamicPrice/Model/Product/Type/Price.php and
/app/core/local/rtega/dynamicPrice/Block/Product/View/Options.php
If you're not already doing so, you need to define the classes like this:
class rtega_dynamicPrice_Model_Product_Type_Price extends Mage_Catalog_Model_Product_Type_Price {
then just redefine the functions you want to modify.
I hope this helps you somewhat!

Are there standard naming conventions for a catalog override module in Magento?

If writing a module to add and modify some catalog logic. Is there anything wrong or against any standards/best practices in creating a module named "Catalog" that lives in the app/code/local directory?
example:
app/
--code/
----local/
------Catalog/
--------controllers/
--------etc/
-or should it be prefixed, something like: Foo_Catalog
I'm specifically looking if best practices/standards for Magento exist for this. (not just opinion)
Best practices would be to in essence extend Catalog via your Module and its specific purpose. So if you are adding/modifying Product's image gallery functionality within the Catalog module your module might be named CompanyName_NewGallery, thereafter you could have a folder structure like the such:
app/
--code/
----local/
------CompanyName/
--------NewGallery/
----------Block/Catalog/Product/Gallery.php
----------controllers/Catalog/
----------etc/
In your config.xml you would set it up so that your Gallery.php would overwrite magento's in the following way:
<global>
<blocks>
<sales>
<rewrite>
<product_gallery>CompanyName_NewGallery_Block_Catalog_Product_Gallery</product_gallery>
</rewrite>
</sales>
</blocks>
</global>
Then declare your class and you can either totally overwrite the class and extend the original class' parent (Mage_Core_Block_Template) or the original class (Mage_Catalog_Block_Product_Gallery)

Magento - how to declare multiple helper classes in the same config

Could someone please tell me how I can declare multiple helpers within the same config file for the same module?
I've been using helper utility files for awhile now, but as my utility method is becoming increasingly long, with many functions, I'd like to split it up into seperate helper utility classes based on the functionality. So I'd have a class called Categoryhelper and one called Attributehelper. Obviously this step I can do, but I'm not sure how to declare these in the config.xml.
I've tried messing around with the config, doing trial and error but cant seem to get anything to work.
Here's what I originally had, using the default helper:
(note - my custom module name is called 'Helper'
<global>
...
<helpers>
<helper>
<class>GPMClient_Helper_Helper</class>
</helper>
</helpers>
...
and here's what I've tried:
<helpers>
<helper>
<class>GPMClient_Helper_Helper/Categoryhelper</class>
</helper>
<helper>
<class>GPMClient_Helper_Helper/Attributehelper</class>
</helper>
and:
<helpers>
<helper>
<class>GPMClient_Helper_Helper/Categoryhelper</class>
<class>GPMClient_Helper_Helper/Attributehelper</class>
</helper>
Should the helper classes go into their own xml fragment or should both be grouped together?
If anyone could please post a sample config with multiple helper classes declared, I'd be most grateful.
Thanks,
Ian
Seems like you got wrong how it works. When you add next lines to your GPMClient_Helper module config.xml
<helpers>
<helper>
<class>GPMClient_Helper_Helper</class>
</helper>
</helpers>
you define class prefix for all your helpers. So, now in your GPMClient/Helper/Helper directory you should create file Data.php with GPMClient_Helper_Helper_Datacode inside and any number of classes named GPMClient_Helper_Helper_*.

Magento - extending the Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection class

OK, so this is leading on from another question I asked here recently. Basically, I want to extend the Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection class, so I can add some extra filters for the product collections that can be re-used throughout my store (such as best-selling). This is meant to replace the following code, which I currently use, which is in my template.phtml file:
$_bs_productCollection = Mage::getResourceModel('reports/product_collection')
->addAttributeToSelect('name')
->addAttributeToFilter('visibility', $visibility)
->addOrderedQty()
->setOrder('ordered_qty', 'desc')
->setPageSize(6);
$_bs_productCollection->load();
So, I set up my module, and it's loading (it shows in the admin/system/config/advanced). Folder structure as follows:
etc/modules/Samsmodule.xml
local/Samsmodule
local/Samsmodule/Catalog
local/Samsmodule/Catalog/etc
local/Samsmodule/Catalog/etc/config.xml
local/Samsmodule/Catalog/Model
local/Samsmodule/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php
local/Samsmodule/Catalog/Helper (not sure if this is needed or not)
My Samsmodule.xml is:
<config>
<modules>
<Samsmodule_Catalog>
<active>true</active>
<codePool>local</codePool>
</Samsmodule_Catalog>
</modules>
</config>
My config.xml is:
<config>
<modules>
<Samsmodule_Catalog>
<version>0.1.0</version>
</Samsmodule_Catalog>
</modules>
<global>
<models>
<catalog_resource_eav_mysql4>
<rewrite>
<product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</product_collection>
</rewrite>
</catalog_resource_eav_mysql4>
</models>
</global>
</config>
And my Collection.php is:
<?php
class Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
{
public function filterbyBestSelling($attribute,$visibility,$_category,$no_of_items)
{
$this->addAttributeToSelect($attribute)->addOrderedQty()->setOrder('ordered_qty', 'desc')->addAttributeToFilter('visibility', $visibility)->addCategoryFilter($_category)->setPageSize($no_of_items);
return $this;
}
}
And then from my template.phtml I call it like so:
$_bs_productCollection = Mage::getResourceModel('reports/product_collection')
->filterbyBestSelling('name',$visibility,$_category,6);
But it's not working - what am I missing? If I just add the code from my Collection.php to the bottom of my core Collection.php file, and use the same call, it works fine.
(Didn't mean to leave you hanging in the other thread, but there's not a quick answer to this one that wouldn't either seem like magic or just confuse people further.)
You don't need to override a class unless you're going to change the behavior of an existing method. You just need to create a new class that extend the existing class. Here's how you do that.
Terminology For the Normal State of Things
Models are the logical classes/objects that define the behavior of some "thing" (product, etc.) in Magento
Models contain Model Resources. Model Resources are the classes that do the actual fetching of data from some datastore (mysql, etc). This is the Data Mapper pattern.
Collections are objects with array like properties that query the database and return a group of Models. Somewhat confusingly, Collections are also Model Resources.
So, in the normal state of things, you might say something like
Mage::getModel('catalog/product')
to get a product model and the underlying system uses
Mage::getResourceModel('catalog/product');
to get the Mode Resource object that queries for a single product, and either of the following are used
Mage::getResourceModel('catalog/product_collection');
Mage::getModel('catalog/product')->getCollection();
to get the Collection object that queries for many models. In current versions of Magento each Model object has a method named "getCollection" which returns its corresponding Collection Resource.
Reports Off the Rails
Reports go a little sideways, but everything is still within the same universe as described above. It turns out there's no such model as a
Mage::getModel('reports/product');
But there is a collection
Mage::getResourceModel('reports/product_collection')
If you look at the class (which you'll be extending below), you'll see that the 'reports/product_collection' collection
class Mage_Reports_Model_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
extends the the base product collection class. In other words, the client programmer working on the reports section had the exact same though you did. "I want to add some methods to to Mage::getModelResource('catalog/product_collection'). They did this by extending the base class.
Shut Up, I Just Want this to Work
So, what you really want to do here is
Create a new class Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection that extends the base Mage_Reports_Model_Mysql4_Product_Collection collection class.
Ensure that a call to Mage::getModelResource('samscatalog/product_collection') returns an instance of the above class by configurig our module to use Models and Model Resources.
We're also going to change you Module structure around a little bit to help ease naming confusion. I'm not a big fan of giving module folders the same names as core modules (i.e. "Catalog"), and the top level folder (after local/) is actually a Namespace, not a module folder. (A namespace may contain many modules)
We are not overriding the class. We are configuring a custom module under your namespace to use both Models and Model Resources. We're then defining a model resource that extends an existing PHP class already in the system. Overrides should only be used when you want to change the behavior of a particular method call. (Appologies for harping on this, but there's enough general confusion in the communiy about this that it's worth harping on over. and over. and over.)
First, we're going to create the module directory structure and files. We'll just need two
local/Samsnamespace/Samscatalog/etc/config.xml
local/Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php
(and don't forget to enable the module in app/etc/modules. If you're not sure what that means, start reading)
The Collection.php file should contain
<?php
class Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection extends Mage_Reports_Model_Mysql4_Product_Collection
{
/* your custom methods go here*/
}
And the config file should contain
<config>
<modules>
<Samsnamespace_Samscatalog>
<version>0.1.0</version>
</Samsnamespace_Samscatalog>
</modules>
<global>
<models>
<samscatalog>
<class>Samsnamespace_Samscatalog_Model</class>
<resourceModel>samscatalog_mysql4</resourceModel>
</samscatalog>
<samscatalog_mysql4>
<class>Samsnamespace_Samscatalog_Model_Mysql4</class>
</samscatalog_mysql4>
</models>
</global>
</config>
With these files in place and the module enabled, you should be able to call
$test = Mage::getResourceModel('samscatalog/product_collection');
var_dump(get_class($test));
and your collection will be returned, and you can add methods to your heart's content.
What's Going On
This is mind bending, so you can stop reading if you want. It's also a rehash of concepts I've covered elsewhere.
When you say
Mage::getResourceModel('samscatalog/product_collection');
The underlying mage system codes says "ok, so this resource model"
samscatalog/product_collection
is part of the
samscatalog/product
model (not entirely true in this case, but it's what the system thinks).
So, since the resource model samscatalog/product_collection is part of the samscatalog/product model, let's look at the config at
global/models/samscatalog/resourceModel
To get the resource model URI of
samscatalog_mysql4
and then let's use that to look at the config at
global/models/samscatalog_mysql4/class
to get the base classname for all Resource Models that are a part of this Module. This ends up being
Samsnamespace_Samscatalog_Model_Mysql4
Which means the samscatalog/product_collection Resource Model is named
Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection
and then its just Magento's standard auto-load which does a
include('Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php');
What is the class of the resulting product collection? Does your override work?
This section seems suspect, I'm surprised if it's actually working:
<global>
<models>
<catalog_resource_eav_mysql4>
<rewrite>
<product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</product_collection>
</rewrite>
</catalog_resource_eav_mysql4>
</models>
</global>
Try this instead:
<global>
<models>
<catalog>
<rewrite>
<resource_eav_mysql4_product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</resource_eav_mysql4_product_collection>
</rewrite>
</catalog>
</models>
</global>
The tag inside of refers to a module. Catalog is a module, while catalog_resource_eav_mysql4 isn't. The tag inside of specifies a class handle, which is basically everything after Mage_Catalog_Model_ in the classname.
Hope that helps!
Thanks,
Joe

Resources