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



Daniel F

Posted

18 minutes ago, DawPi said:

I'm just curious, @Daniel F as far I remember you wrote that your SEO app will be ported into v5. But how? I can count all hooks used by this app and there are ~ 15 file hooks. Many of them are hooked into "not allowed by v5" areas. So how? 🙂

1. You should all cool down and wait for the upcoming news and also the final product before getting in such a  panic rage.

2. Please see my reply in the SEO topic:

On 7/25/2023 at 8:07 AM, Daniel F said:

 I'm not sure yet if all the features will work or if some will have to be removed

3. See the first point. We're listening to feedback and implementing changes based on it, just like Esther and Matt implemented changes today based on the provided feedback.

4. I think you're all way too scared.

There's still so much that can be done, it's 2023, and there are other ways and solutions than to edit files..

4 minutes ago, Charles said:

Sure. Basically, when we think Daniel, we think llamas.

ALPACAS! I'll repeat very very slowly just for you: AL PA CAS

  • Management
Matt

Posted

I completely understand the anxiety and I get the fatalism, but please have patience. Wait until we have laid out the suite of tools. Then consider if some of your mods are even worth porting over. Consider your highest quality apps and then let us know if you need guidance on how to migrate them to v5.

Remember this is breaking news. Some of this code was only finished a few days ago. We are in the pre-pre-alpha phase. We are releasing news and listening to feedback, so there is no need to panic.

Also keep in mind that v4 will be maintained until 2025 at least.

teraßyte

Posted (edited)

18 minutes ago, Matt said:

But it can’t continue. In the past, we’ve changed the signature params in getItemsWithPermissions() and had to patch the release as tickets pile up as apps which overload that just break.

Internally we have a rule not to touch function params of commonly hooked methods. It means we can’t make changes to our PHP code without breaking loads of client sites. This means we can’t clean up and modernise our own code.

There's a really easy way to avoid breaking methods: use a single array for every method and pass all values in that array.

Need to add a new value? The array has a new index. 😋 😹

Edited by teraßyte
Adriano Faria

Posted

@Matt @Esther E.

Nit sure everything is listed in the content listener, but would be helpful to listen when a user:

- react/unreact to a content (specially this one which is a trait).

- follow/unfollow a content.

In both, returning member ID, content type (global, not per app) and content ID.

Probably there are more. I’ll make another post if I remember. 

Thank you.

Esther E.

Posted

11 minutes ago, All Astronauts said:

I typed "The PHP programming language crying" into an AI image generator and all it gave me was a sullen, cosplaying Esther. BTW, next concert flyer? This.

Could contain: Adult, Female, Person, Woman, Face, Head, Formal Wear, Anime, Dress, Comics

Maybe a cosplaying me from 20 years ago....

Ocean West

Posted

So with the listeners and actions, if I got a notification to tend to approve a post would the suite be smart enough to dismiss the unread notification? Not just for me but to dismiss it for other moderators as someone took action on the event that required notification? 

 

 

Esther E.

Posted

1 hour ago, Adriano Faria said:

@Matt @Esther E.

Nit sure everything is listed in the content listener, but would be helpful to listen when a user:

- react/unreact to a content (specially this one which is a trait).

- follow/unfollow a content.

Good ideas, we've started a list.

Esther E.

Posted

39 minutes ago, Ocean West said:

So with the listeners and actions, if I got a notification to tend to approve a post would the suite be smart enough to dismiss the unread notification? Not just for me but to dismiss it for other moderators as someone took action on the event that required notification?

That's not really something that would be handled by a listener; if anything, it would be in the core code. That said, I'm not entirely sure that what you're suggesting is the correct behavior. What if one moderator approves a post and another moderator disagrees with that approval? I don't want to go off topic here (as I said, it's not really a "listeners" thing), but it would be an interesting point of discussion.

Adriano Faria

Posted

19 minutes ago, Esther E. said:

Good ideas, we've started a list.

For member listener:

- Visit a profile

- Ignore/stop ignoring something (posts/messages/mentions).

- Enable/disable messenger


All the stuff I’m suggesting is to replace code hooks from existing apps/plugins.

Thank you.

Esther E.

Posted

53 minutes ago, Adriano Faria said:

Visit a profile

This can be handled with a Member listener onProfileUpdate (change to pp_last_visitors)

53 minutes ago, Adriano Faria said:

Enable/disable messenger

This as well. (members_disable_pm)

53 minutes ago, Adriano Faria said:

- Ignore/stop ignoring something (posts/messages/mentions).

This one I'll add to the list for discussion.

Adriano Faria

Posted

12 hours ago, Esther E. said:

This can be handled with a Member listener onProfileUpdate (change to pp_last_visitors)

I don't think this is enough, though. If a member is logged anonymously, the visit isn't registered.

Esther E.

Posted

9 minutes ago, Adriano Faria said:

I don't think this is enough, though. If a member is logged anonymously, the visit isn't registered.

I can think of other ways to accomplish this, but we're not at a point where I can get into how without causing confusion. Suffice it to say, I do think it's still possible. 

RevengeFNF

Posted

Wow... Things went to the wrong side. It will be too bad if Ips loses Adriano.

I have more installed, but i basically only use 2 plugins.

19 hours ago, A Zayed said:

Will stick with IPS4, maybe until IPS version 6 🙃🤦‍♂️

One from Zayed, the External Link Rich Embed. I think a thing like this plugin should've come with the base suit, but it doesn't. Hope this one doesn't belong to the list of the 80% of plugins that will die because of framework limitations.

19 hours ago, Nathan Explosion said:

Thank you - that's several project dead in the water then.

And the other one is from Nathan, oembedServices Manager, so we can oembed services that do not come with IPS. Another one i think it should come with the base suit, but it doesn't come.

I only really need those 2 plugins, so i think i'm more or less safe. Let's see what the future brings.

Marc

Posted

4 minutes ago, RevengeFNF said:

Hope this one doesn't belong to the list of the 80% of plugins that will die because of framework limitations.

It does need to be noted, this is very much a case where someone says "someone may have" and by the time it hits the end the believe is the person did, and admitted it. The 80% there was not from invision, and also not referring to all marketplace plugins. It was from a plugin author relating to their own plugins. It was also an assumption without yet having all the information to make the statement those 80% are not possible. (As we havent shown everything yet, and also gathering feedback on some items).

Clover13

Posted

 

So regarding this assumed 80% of plugins being lost, the main questions I have are:

  1. Can similar results (i.e. a client wants X added/enhanced to any part of the suite) be achieved with whatever IPS is developing for v5?  Maybe in a different way, but the same end result/solution for a client?
  2. If so, will the solutions be Marketplace sellable assets for developers?
  3. If not, how does IPS plan on addressing this clear gap in providing functionality to clients that Marketplace devs previously filled in v4?

I can't imagine IPS removing the ability for devs to enhance the IPS suite in ways that IPS isn't willing to invest in doing themselves.  That would be detrimental to all parties involved.  And history (per the number of Marketplace assets) shows there are A LOT of assets/resources clients want and use that aren't part of the suite.

Marc

Posted

5 minutes ago, Clover13 said:

So regarding this assumed 80% of plugins being lost,

Please re-read my message above. This was one person assuming 80% of 'their' plugins 'may' be 😄 

With regards the other questions, its much better to wait until there is more released and the authors themselves state what can and cannot be achieved before going down that route.

  • Management
Matt

Posted

I'd be surprised if only 20% of currently available plugins and applications were possible with v5. There may need to be some refactoring, some adjustment of the feature set but it's too early to say "well, we're going to lose 80% of the marketplace".

Clover13

Posted

4 minutes ago, Marc Stridgen said:

Please re-read my message above. This was one person assuming 80% of 'their' plugins 'may' be 😄 

With regards the other questions, its much better to wait until there is more released and the authors themselves state what can and cannot be achieved before going down that route.

Regardless of the percentage that is actual or perceived (unless it's 0% being lost), the questions still remain.  They are important questions from both a client and Marketplace developer perspective.  What is the roadmap of the IPS suite and developer toolkit relative to these questions?  IPS is developing the suite, the Marketplace devs are just adopting it with whatever tooling they are provided by IPS.  IPS knows whether Marketplace devs will be able to achieve the same things (even if it is in a different way/method).

  • Management
Matt

Posted

I'll repeat what I said in my first blog:

Quote

Invision Community 5 represents a much-needed reset. It is a moment to reassess everything we know about extending frameworks and construct definitive pathways and workflows that serve you better.

Our aim is for you to continue crafting exceptional applications that bring fresh functionality to the Invision Community while protecting the integrity of our core functionality.

A Quick Recap

  • Generic broad reaching tools such as monkey patching and template overloading have been removed.
  • New precision tools with a specific use-case have been created.
  • There are less opportunities to overwrite and change our UI and functionality but easier ways to extend and create new functionality.

We are being very intentional in restricting what can be changed with regards to our functionality and UI. None of this is by accident or an unintended consequence. We are providing tools to create features that side alongside our functionality, and less opportunities to replace our functionality.

We will have a better suite of development tools to enable this.

The third party developers are very important to us, but most customers choose to not use add-ons or modifications. Based on statistics we collect, the most popular plug-in on the marketplace has less than 250 current installations, and the most popular application has less than 600 installations.

    All Astronauts

    Posted

    Peanut gallery request.

    As everything is being thrown under the aegis of Applications in the 5.x line, I'd rather not have that ACP page just clown-car out with a single (in some cases exceedingly long) list. Similar to Toolbox how about three tabs:

    IPS Apps, 3rd Party Apps that have their own Content Item classes (or things with the Content Router extension maybe?), 3rd Party all-the-rest. You get the gist.

    Any permutation of such to keep the clutter down would be very welcomed.

    RevengeFNF

    Posted

    1 hour ago, Matt said:

    The third party developers are very important to us, but most customers choose to not use add-ons or modifications. Based on statistics we collect, the most popular plug-in on the marketplace has less than 250 current installations, and the most popular application has less than 600 installations.

    But the percentage of clients that used the marketplace is very high, or the majority don't have a single plugin/app installed?

    • Management
    Matt

    Posted

    I’m unsure what the question is there. 🙂 

    Kirill Gromov

    Posted

    2 hours ago, Matt said:

    The third party developers are very important to us, but most customers choose to not use add-ons or modifications. Based on statistics we collect, the most popular plug-in on the marketplace has less than 250 current installations, and the most popular application has less than 600 installations.

    I think it's because you are not interested in developing the market. I see a trend to close the community in the future in the cloud with paying customers, they are more profitable. IMHO. One of the advantages of IPS was its good extensibility and variety of applications and extensions.

     

     

     



    ×
    ×
    • Create New...