Jump to content

IC5: Introduction to Listeners

I'm very excited to be posting my first blog entry for IPS, and thrilled that this is what I get to post.

When we started planning the new development tools for v5, we looked at existing resources - from the marketplace, from some contributors, and from our own managed clients - and asked, what is it that developers find themselves doing the most often? Matt’s previous blog entry gave a brief summary of some of those functions. Today’s blog entry is going to focus on one of our powerful new tools, Listeners.

One common reason for a code hook was to execute custom code when a specific action occurs. For example, when a topic is created, or when a new reply is posted. Listeners allow you to execute your code at key points in the workflow, without the worry of finding exactly the right hook location.

Here is an excerpt from the BlogComment listener in our Cloud application:

Could contain: Electronics, Screen, Computer Hardware, Hardware, Monitor, Computer, Pc, Page, TV, Business Card

 

Creating Listeners

Let’s start with the application’s Developer Center.

Could contain: Page, Text

We’ve added a new tab for Listeners. This tab lists all your existing listeners, as well as the class on which it is listening.

You’ll notice that each listener can only observe a single class. While this may seem slightly tedious, the idea here was that as a developer, you should be conscious of what class you are working with. It also eliminates the need to check what type of object is being passed preventing accidents and unintended consequences when missing class checks.

When you add a listener, there are several listener types available. We will discuss each one in detail.

Could contain: Page, Text, Computer, Electronics, Pc, White Board

 

Content Listener

This listener is fired on an Item or Comment (or Review) class. When adding a Content Listener, you must specify the class you are observing. When you hit Save, there is a validation check in place to ensure that the class exists, and that it is a valid class for the selected listener type.

Content Listeners have the following methods available. All methods are included in the default listener file that is generated.

  • onLoad
    Triggered when an object is loaded (in Content::constructFromData)

NOTE: Be careful! This event could be fired at unexpected times. If you’re executing code here, you may want to check the dispatcher instance to verify that your code is running where you expect.

  • onBeforeCreateOrEdit
    Fired when a form is submitted, before it is saved. This is the equivalent of Item::processBeforeCreate and Item::processBeforeEdit. This method includes a parameter to indicate whether this is a create or edit.
  • onCreateOrEdit
    Fired after a form is saved. This is the equivalent of Item::processAfterCreate and Item::processAfterEdit. This method includes a parameter to indicate whether this is a create or edit.
  • onDelete
    Fired after an object is deleted.
  • onStatusChange
    Fired when any moderation action occurs. For example, when an item is pinned/unpinned, locked/unlocked. The moderation action is passed as a parameter so that your code can take that into account.
  • onMerge
    Triggered AFTER an item is merged.
  • onItemView
    Triggered when an item is viewed and the view count is incremented.

 

Invoice Listener

An Invoice listener is fired only on the \IPS\nexus\Invoice class. This listener does not require you to specify a class to extend.

The Invoice listener includes a single method, onStatusChange. This is fired when the invoice is saved and the status changes (pending/paid/expired/canceled).

 

Member Listener

The Member listener will be familiar to many of you. We have taken the MemberSync extension and moved it in its entirety to a listener, as it was a better fit for this structure. All the previous methods that were available are still available here. We have also added the following new methods:

  • onJoinClub
    Fired when a member joins a club. If approval is required, this is fired after they are approved.
  • onLeaveClub
    Fired when a member leaves or is removed from a club.
  • onEventRsvp
    Fired when a member responds to an event. The response is included as a parameter to this method.

 

Commerce Package Listener

The Commerce Package listener is fired on any implementation of \IPS\nexus\Invoice\Item. You must specify the class that you are observing.

The methods are the same as those that are available in an item extension.

  • onCancel
  • onChange
  • onDelete
  • onExpireWarning
  • onExpire
  • onInvoiceCancel
  • onPaid
  • onPurchaseGenerated
  • onReactivate
  • onRenew
  • onTransfer
  • onUnpaid

 

Some Technical Notes

  • All listener files will be generated in a “listeners” directory within your application.
  • Your application’s data directory will include a listeners.json file that defines all your listeners. The json file is automatically generated when you add/remove a listener.
  • All listener methods are optional. The default class that is generated will include all available methods, but they do not have to be present in your file.
  • All listener methods are return type void.
  • If a listener method fails, an exception will be thrown when IN_DEV is enabled. In production, the exception will be logged with a reference to the listener class and the event on which the exception occurred.

 

Firing Events

Your code can fire any existing event using the Event::fire method.

Example:

Event::fire( 'onBeforeCreateOrEdit', $comment, array( $values ) );

The Event::fire method is called statically and accepts an event name, the object on which the event will be fired, and an array of additional parameters (varies according to the event that you are triggering).

This concludes our introduction to Listeners. We do intend to implement additional listener types and events based on your feedback and as the need arises.

Comments

Recommended Comments



Esther E.

Posted

43 minutes ago, Adriano Faria said:

@Esther E.

Just to confirm: will this return all data from the invoice? I mean, I need at least the i_items, to see if the invoice belongs to a purchase of a Downloads file.

Thank you.

Listeners don't return any data at all. I'm not quite following the question, can you please clarify? 

Adriano Faria

Posted

12 minutes ago, Esther E. said:

Listeners don't return any data at all. I'm not quite following the question, can you please clarify? 

I need to move users to another group when they make a purchase a file in Downloads. Is there any way to get that information?

An achievement rule could be an easy way to do it but there isn’t such a rule currently.

Esther E.

Posted

49 minutes ago, Adriano Faria said:

I need to move users to another group when they make a purchase a file in Downloads. Is there any way to get that information?

An achievement rule could be an easy way to do it but there isn’t such a rule currently.

You want to use the commerce package listener, not an invoice listener.

Adriano Faria

Posted

13 minutes ago, Esther E. said:

You want to use the commerce package listener, not an invoice listener.

Ok. Somehow I thought it would be tied to a product (package) due to its name. Guess I’m wrong?

Thanks.

Esther E.

Posted

3 minutes ago, Adriano Faria said:

Ok. Somehow I thought it would be tied to a product (package) due to its name. Guess I’m wrong?

Thanks.

Yes, it's fired on \IPS\nexus\Invoice\Item. you specify the item type you want to listen on, so in your case you'd create a listener on downloads\extensions\nexus\Item\File.

Adriano Faria

Posted

12 minutes ago, DawPi said:

Did you managed it or got a reply?

This:

But I didn't try it yet.

DawPi

Posted (edited)

Woah, totally forgot it. I'll give it a chance, thanks!

Edited by DawPi
DawPi

Posted

15 hours ago, Daniel F said:

You could use this approach

 

Works! Thanks!

 

Can I ask a question? What if I or other developers use it more frequently to maintain different types of mods? Will it slow IC5 down too much?

 

 



×
×
  • Create New...