Magento Dispatching and Catching Events - magento

I am dealing with Magento for a while and i find it very interesting and probably my future choice of work tool. Though i have some troubles understanding some of the stuff going on. If i call www.store.com/catalog/product/view/id/2 then the product controller executes from the catalog core module, in it the product is being fetched via _initProduct() method first in which this event is being dispatched:
Mage::dispatchEvent('catalog_controller_product_init_before', array('controller_action'=>$this));.
Which class/method is being called? As i understood that should be a method from observer class which is under Model folder and it should be defined in the etc/config.xml file.
Some of the events defined in the config.xml are executed automatically... (why?) where is defined the one used in the viewAction() from the ProductController.php in Catalog module? How i can send and use array data to the observer's methods, cause i saw some of them contains this method: Mage::app()->reinitStores() which re-inits store, group and website collections and it's not something simple. I find this very powerful and i really want to know the posibilities with using Observers and Events.

Event observers can be defined in the config.xml for any module that is active in the system, they don't necessarily have to be defined in the same module.
You can send data to the event observers by adding information to the event object, which is done in an array defined as the second argument to dispatchEvent. Just add more elements to the array and the event observer method can extract it from $observer->getEvent(). You are also free to define your own events by calling the same dispatchEvent method.
One of the handy things about most Magento models is that they are inherited from the Mage_Core_Model_Abstract class which includes event for _load_after, _save_before, _save_after, _delete_before and _delete_after. For example, the product model has catalog_product_load_after, catalog_product_save_before, etc.
Hope that gives you some more information about the possibilities of using events.

Related

Is it appropriate to use request data in model observer or model event listener

I want to make an observer class for one of my models for saving data.In the observer class, I need to get data from the form.I am wondering if it is appropriate to use request object in the observer class.I have never seen anyone uses it that way.

What is the correct place/bundle to place this action

Say I have a CoreBundle, which has an entity called Event. In the CoreBundle, events can e.g. be shown (showAction). I also have a BackendBundle. The event's deleteAction can only be triggered from the backend. However, the deleteAction belongs to an entity that is defined in the CoreBundle. Both the CoreBundle and the BackendBundle have an EventController.
The question is: Should the deleteAction be placed in the BackendBundle's EventController or in the CoreBundle's EventController?
P.s. I know both will work, but this is more somewhat of a phylosophical question.
I would suggest you have a BackendBundle with an EventController and a deleteAction. This deleteAction may call a specific handler (or manager or whatever) inside the CoreBundle, but I would keep the controller code inside the BackendBundle.
First, it makes it easy to follow the code without switching bundles. I can see that the request comes in, that either the entity is deleted or that some manager is called and that a redirect is send or a template is rendered.
Second, and way more important, is that if you introduce another bundle which has a deleteAction for the backend, you can either have different ways of handling them (one inside it's own bundle and one inside the CoreBundle) or you have to name them different and create a big mess.
In generell, I stick to the rule to have the controller inside the same bundle where the route and the view lives and only share the model. In case of a CoreBundle, I handle deletion with a manager between the controller and the model. In your case the deleteAction would get a EventManager service and call a delete with either the object or an id (depending on my needs). This way the code executed to delete an event is in one place and can be changed easily.

Extract Order information and customer information from new order email

I want to extract Order information and customer information from new order email which is sent to the customer after purchasing any product from Magento Website.
I have tried a lot but not getting any results as such.
Is this possible in Magento, I am stuck up in this problem since days.Does any one have a solution to this?
The sending of new order emails is handled in Mage_Sales_Model_Order.
Most Magento model classes (all which extend Mage_Core_Model_Abstract) implement the Template Method pattern - not to be confused with view templates. The template methods can be used to hook in to save, load, and delete workflows in two ways:
Method rewrites via config-based class overrides (another Magento treat)
Observe events dispatched in the template methods.
By far the preferred technique for hooking into model execution is the event-observer system. Additionally, there are hundreds of events dispatched throughout Magento for any given execution.

Which event should I use just before a page is shown on browser on Plone to trigger a subscriber?

I want to create a subscriber that gets triggered when the user tries to access the resource (which is a custom content-type). So, the object is not being added, modified, nothing, is just being traversed. Something like a Zope View Event.
So, basically, suppose a custom content type has a custom workflow (two states: private and viewed). The initial state is private. This content type is only going to be created programatically, using _createObjectByType by anonymous users. Suppose an object called myobjet was added, programatically, to the root folder of my Plone site.
What I want is: when the user access
http://localhost:8080/Plone/myobject
...it automatically changes the state of the workflow of this object to viewed. The url http://localhost:8080/Plone/myobject is going to be a custom view, not the default base_edit.
Which event should I use? I tried IEndRequestEvent and IBeforeTraverseEvent from this list and none of them work: the handler is not being called for my custom object interface.
I've tried other events with my custom object interface (like IObjectEditedEvent), and, for this event, my handler is called when I edit an object that implements the interface. But using IEndRequestEvent and IBeforeTraverseEvent doesn't call the handler.
IEndRequestEvent and IBeforeTraverseEvent only work when I set the subscriber to all interfaces:
<subscriber
for="*
zope.app.publication.interfaces.IBeforeTraverseEvent"
handler=".subscriber.myhandler"
/>
And when I make myhandler print the object and the event in this situation, it shows:
<PloneSite at Plone>
<zope.app.publication.interfaces.BeforeTraverseEvent object at 0xd52618c>
If the solution is to write an event myself, is there an easy tutorial for this?
You might want to have a look at http://pypi.python.org/pypi/plone.validatehook.
Make sure you bind the event to the right interface. If you bind it to "Interface" (as described on the plone.validatehook pypi page) the event will get called for every single request. In order to restrict the event to contentish objects you can do the following:
from Products.CMFCore.interfaces import IContentish
#adapter(IContentish, IPostValidationEvent)
def RedirectMember(object, event):
...
(Edit: I removed my first answer because it didn't work)
Not sure what this subscriber is supposed to do, but if the object is not being modified, added or whatsoever than I must suspect it will just be viewed...so why not just use the __call__ method of the items view (or the __update__ method if you are using five.grok/dexterity)?

Magento: What is the best way to extend Magento to add a class that is called on every page load

I am looking to create some new functionality to Magento. I am going to be looking to the url and grabbing a parameter. The issue is, this can be on any page. So I can't just extend a Catalog or Checkout Module.
I thought about extending the session classes but I wasn't sure it really fit. Basically I want to grab a parameter from the url and from there add some functionality if it is set or not. I don't think a class will get auto loaded unless it is instantiated somewhere else with a getModel method, am I wrong?
How can you add a module that doesn't have a url path for controller and what not, but doesn't fit extending one of the core modules?
I looked for a generic event but didn't really see one like before_page_load or something
Take a look at the event controller_action_predispatch in app/code/core/Mage/Core/Controller/Varien/Action.php. This event should get called on each dispatch and allow you to grab whatever parameters you need.
The event passes the controller as data, so you can do this:
function yourEvent( $event ) {
$controller = $event->getController();
// your processing here
}
Let me know if that doesn't fit the bill. Hope that helps!
Thanks,
Joe

Resources