In Magento, I want to modify the code of an Abstract class. Specifically, I want to modify the behavior of the function _getReadAdapter() of the class Mage_Core_Model_Resource_Db_Abstract.
According to this article by Alan Storm, http://alanstorm.com/magento_upgrade_rewrite_override, there are three ways to do it. Modifying the Magento's source code is very bad and not encouraged. On the other hand, it seems to me that I cannot use Magento's override/rewrite system, since the abstract class is neither a model, helper nor block. Is that correct?
As such, the only way to go about this is to make a copy of this particular source code at app/local/Mage, and modify the code of this new copy. Is that right?
Yep, using the codepool app/code/local is the way to go.
This is because abstract classes are not handled by the Magento factories, but literally extended in the class definitions.
Actually you should not modify abstract class, instead, you should modify the derive class that extends this abstract class
Related
I am talking about concern/module/extensions as they exist in Ruby and Swift for example.
A Ruby module is something that a class can include (= add the module functions as its own instance methods) or extend (add the module functions as its own class methods).
A swift extension is also an add-on for class, typically when you want to add a functionality you would first define the prototype, then implement it in an extension.
(please correct me if I'm wrong)
How would you represent such a Ruby module/Swift extension in UML, and its link to the class it is included in/it extends ?
I also don't know a standard for this, but would model it like this:
A Realize relation with an <<import>> stereotype. Maybe the Realize is too strong in the context and a simple Dependency but still with that stereotype would be better.
Not everything is available natively in UML. But like in any language, if you don't have a single word for a thing you can make constructs that describe the thing. You are rather free in choosing your vocabulary. Only you should be consistent in the domain where you use such a paraphrase.
As title suggest i want to override Mage_Payment_Model_Method_Abstract class , I know that it is abstract class. and we can easily override abstract class using local directory like app\code\local\Mage\Payment\Model\Method\Abstract.php. But i want to know is there any other option for me ? Because this option is not safe with different magento version.
Any help will be appreciated.
Thank you
'Override' is a method where you copy a class from the Magento core into the local code. For ex:
app/code/core/Mage/Rule/Model/Abstract.php
to
app/code/local/Mage/Rule/Model/Abstract.php
An override is where you tell Magento to "Use this class file instead of the other class file". Similar, but different from a rewrite. Rewrites are considered better practice because they're less likely to cause problems with upgrades and extension compatibility.
An abstract class is never instantiated, it can never be rewritten.
If you override, you need to take care of future upgrades. You can't rewrite an abstract class. The rewrite system works because Magento uses a factory pattern to instantiate model, blocks, and helpers.
The other alternative is to use a traditional class override. For ex: Copy
app/code/core/Mage/Rule/Model/Abstract.php
to
app/code/local/Mage/Rule/Model/Abstract.php
Also somewhere on the blog I read this (not in favor though) For ex: Copy
Mage_Shipping_Model_Carrier_Abstract
from
app/code/core/Mage/Shipping/Model/Carrier
to
app/code/local/Mage/Shipping/Model/Carrier
Do NOT change the class name, just change or add the methods as you need.
This is a trick. Magento loads a class from several locations, and app/code/local comes before app/code/core
Good luck!!!
Could somebody explain is it possible to have potected, pivate methods in playfamewok's contolles except:
public static void method-action-name() {}
For example if I would have method like this:
protected static int doSomeWork() {}
and this method would be invoked in method-action-name() ..
public static void method-action-name() {
...
int resul = doSomeWork();
...
}
I do not want to have long action-method, so I would like to split it to smaller ones, and then reuse it in other action-methods.
I mean is it ok (from playframework's point of view) to have such method in controller side instead of having them in domain classes? In Spring Framework, we use BP (business process) beans for that, for example.
Is it ok to have such helper methods for business methods in playframework controllers ?
Added after having answer & comments:
For example if I have SearchController class then for that class would be nice to have methods like preSearch1(), preSearch2() what search() method would use, but if I move these methods (1,2) to another class then it should be class with name like SearchHelper then? in package named /src/helpers.. not very nice because they related to search too. But maybe then into /src/bp/SearchBP (bp=business-process). And then in controllers/Search i use /bp/SearchBP that use some Model object with .save() DAO methods (SearchBP can use Domain methods and Search class can use Domain methods as well)
The question here: what class ant package would be nice for those methods? (i just did watch it in examples - there alway very simple usage of controllers that use domain object that why i ask)
yes, you can. Controllers are normal classes, you can add whatever you want. It may not be recommended to clutter them with helper methods, I personally would move them to another class, but you can do what you say.
ANSWER TO EDIT:
The name of the package is "irrelevant", won't change it too much :). You can put them under controllers.support.search which would mean controllers.support is a package with helper classes and the subpackage search contains helper classes and methods related to search.
One alternative (which I like more) is to create a Service layer for that, in a "services" package. You seem to come from a Spring background, so it should come naturally to you. These services are instantiated in the controller as required, or maybe just used via static methods, and do the main business logic. That way the controller only tackles the "higher level" logic.
Another alternative is to move as much of that logic as possible into the Model (avoidid the Anemic Domain Model), and using the Model classes from the controller.
As most decisions in development, which one is better depends on your experience, possible impact/limitations in the codebase, practices in your project... anyway, you can always refactor. Just choose the one that you are more used to (it seems to be Services approach) and code away :)
Any behaviour that's complicated enough to be described as "business logic" (rather than "presentation logic") belongs in the model, not the controller. If your model does nothing but map to/from a set of database tables, then it isn't doing its job properly. Things like permissions and access control, in particular, should be enforced by the model.
I want to have an abstract base class for some of my custom UserControl's. The reason is obvious: they share some common properties and methods (a basic implementation of some elements of an interface actually), and I want to implement them only once.
I have done this by defining my abstract base class:
public abstract class ViewBase : UserControl, ISomeInterface
Then I went to implement one of my views, as usual, with the designer:
public partial class SpecialView : UserControl //all OK
Up to here all is fine. Now I replace the derivation of my SpecialView class with the abstract base class:
public partial class SpecialView : ViewBase //disrupts the designer
Now, the designer in Visual Studio 2008 won't work anymore, stating: The designer must create an instance of type 'ViewBase' but it cannot because the type is declared as abstract.
How can I circumvent this? I just do not want to have the same code copied for all those views.
Info: there is a question question with virtual methods, instead of abstract classes, but there is no suitable solution for me.
Instead of using abstract class, you can mark the functions virtual and override them in the inheriting classes
The best solution is here:
http://wonkitect.wordpress.com/2008/06/20/using-visual-studio-whidbey-to-design-abstract-forms/
Using it now, it's elegant and gets around the underlying problem without breaking your nice OOP design.
Try this solution from Urban Potato, which worked for me, with a strange side effect that I never really had explained, and never got a good workaround. Maybe you'll get lucky and won't have that side-effect!
One could argue that it doesn't make sense in terms of design philosophy to expect to be able to work with an abstract control in the Designer. An abstract class tends to model a type of object for which simply knowing that it's an 'X' doesn't adequately describe it - there's no such thing as an abstract Bird or Car, it's always a specific type of bird or car. Looking at it this way, if you want to view a custom control in the designer, it has to be a specific type of control rather than an abstract one, otherwise what are you looking at? I can see why it's annoying, but I can also see why the Designer was coded in this way.
I would like to check if my assumption about codeigniter is right ?
We would normally extend a class when we are trying to include more functionality to the core, such as MY_Controller extends Controller, MY_Model extends Model etc...
But for example, if we are in the checkout library retrieving some checkout info(eg, product_id), we can just $this->load->library('product_lib',array('product_id'=>$product_id)) and we can easily $this->product_lib->product_name etc... from the checkout library right?
The $this->load thing is kind of equivalent to "hard code" checkout library to extend product_lib(class checkout_lib extends product_lib) to be able to use whatever methods/variables there is in the product_lib.
Please enlighten me.
In CodeIgniter $this->load is like having a resource manager (e.g. resourceManager->load("path/to/file")) and it takes care of loading the library, and passing any arguments you specify and such, easily allowing you to quickly get to using it.
So if you have a variable named product_name in your product_lib then yes calling $this->product_lib->product_name will be accessing that variable.
Really it just places the library into an array with the library name as the key and the instance of the library as the value so calling $this->product_lib is really calling something similar to $loadedLibraries['product_lib'] and returning the instance.
I hope that answers what you are asking, I'm quite tired and could have miss understood you question.
I think you misunderstood the OO paradigm and the way CI work.
$this->load is same with instantiate an object of the library/model, or load the helper file. CI have some sort of management to see if the helper/library/model already uploaded or not.
In other hand, the extends is used when defining a class, to tell PHP that the class will be inherit the parent class properties and method. A class is a blue print of object it will produce.
Maybe you can start by understanding the OO concept first. You can read this as a start, and see the reference used there.