netcarver

Prioritising hooks for same event.

Recommended Posts

Am I right in thinking that multiple hooks that are added for the same event can be prioritised by doing something like this...

$session->addHookAfter( 'login', $this, 'myLoginHook', array('priority'=>xyz) );

Where xyz is the relative priority for the hook and the lower the value, the earlier it will be called as the hooks are executed?

  • Like 1

Share this post


Link to post
Share on other sites

That's correct. At least, that was the intention. It's one of those things I thought would come in more handy than it has… I'm not aware of it ever being used. So I think the only time it has even been tested is when I originally coded it in there (at which time it was working). No recent confirmation of current functionality though. A quick glance in the code seems to indicate that it should work as intended, though please let me know if you find otherwise.

Default priority level is 100 (that's what gets assigned when none assigned).

  • Like 1

Share this post


Link to post
Share on other sites

Ok, an update. To get two of my modules to work well together I do need this functionality. I basically want the 2-factor login module to get first crack at the hook before the login alarm gets to log/email the users.

I set the priority in the 2-factor module to 10 and in the alarm module to 2000 (just to be sure) however on adding a die(__CLASS__) to both hook handler routines I could see that the alarm module was getting called first. An unexpected result, but I've now found out why.

It turns out that I was hooking the login event in slightly different ways and this does seem to effect the order the routines get called in. In the 2-factor module I was doing this...

$this->addHookAfter( "Session::login", $this, 'my2FactorHook', array('priority'=>10));

Whilst in the alarm module I was adding the hook differently...

$this->session->addHookAfter( "login", $this, 'myAlarmHook', array('priority'=>2000));

Switching the 2-factor init() routine over to using $this->session->addHookAfter('login'...) has everything called in the right order.

  • Like 1

Share this post


Link to post
Share on other sites

Glad you got it working. Static hooks ("Session::login") are treated separately from direct hooks. The direct hooks are more specific so they get executed before the static ones. But I wasn't really thinking much about priority level when building this, so not sure if that's the way it should be or not.

Share this post


Link to post
Share on other sites

Ok, that certainly explains the result. But it makes me wonder if a unified approach to hooks might be more logical than having a set of static hooks and local hooks unless there was a specific reason for going for two sets?

Share this post


Link to post
Share on other sites

Static hooks apply to all instances of a class, whereas direct instance hooks apply to just 1 instance (the one you assign it to). For example, you'd use a static hook if you wanted to hook into or add some new method to all Page instances. Whereas, if you are hooking any API variable ($session, $pages, $modules, etc.), it's better to use a direct/instance hook since there is only ever going to be 1 instance of those variables anyway. While you could use a static hook anywhere, direct hooks are a little more efficient because they are stored with the actual object instance rather than in the larger pool of static hooks. Meaning, direct/instance hooks result in less for ProcessWire to sift through when executing hooks (though it probably doesn't matter much in the larger scheme of things). But this is also the reason why they aren't prioritized together, as they are stored in different places.

  • Like 1

Share this post


Link to post
Share on other sites

Just thought you guys might like to know that the priority setting just got another user :)

Needed to solve the conflict between RedirectIds and 404Search modules.

Thanks again Ryan for thinking of everything!

  • Like 6

Share this post


Link to post
Share on other sites

I thought it might be worth mentioning - given remarks above - that another three years on this feature is still getting new users :D

This time, it's to fire off my own page-renaming module before the Custom Upload Names module makes updates when the page name changes.

This has allowed the modules to work together really easily and, I suspect, saved quite a lot of hard work!

  • Like 4

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By cosmicsafari
      Hi all,
      I am using the formSubmitSuccess form builder hook to send a copy of the form submission to a third party.
      However I couldn't figure out how to get the submissions form type at this point, the reason being is that I only want to send the data onto the third party for certain form types.
      I don't have the submission details being passed into the hook, wasn't sure how to achieve this so at the moment I have it doing a DB query to pull the latest submission details for that form type so I'm rather stumped about how I can go about achieving this.
      Hope thats makes sense.
    • By joe_g
      Hi there,
      I'm trying to limit a specific user can only add pages as a child (under) a page created by themselves.  
      The discussion in this thread gets close, it's a working solution on how to only allow editing on pages you created yourself. I'm using this and it works well. But I'm not sure how to modify this for my purposes. 
       
      I'm suspecting I need to do to something like
      $this->addHookBefore("Page::added", $this, 'added');
      then in "added" check if parent is created by the current user. But I'm a bit lost on how exactly to do this.
      thank you! /J
       
    • By suntrop
      Sometimes I need pages in the site tree that are basically just a reference to another page – to redirect to the original page or display the same content under the new page url.
      I was surprised I couldn't find anything like that in the forum or as a module already. However, there is a new module by @Robin S but not exactly what I need.
      Example
      Home News Press Newsroom Media Services About Newsroom (virtual page for /news/newsroom/) Contact Example I: The page /about/newsroom/ should act as /news/newsroom/ – so, wehen I loop all pages for a sitemap both pages should have the URL /news/newsroom/.
      Example II: Another example (not often used) would be tu display the exact same content on /about/newsroom/ – although the page itself has no content on its own.
      Those examples don't have much in common, but they are just virtual or fake pages in the site tree.
      While the second one should be an easy task with wireRenderFile(), the first example isn't quite obvious to me. I think I have to use hooks and I have no idea where to start. I really appreciate you guys come up with a solution for everything, but I need to learn this myself  So just some hints to start would be great!
      Do I put the code into a module or some of the _init.php, ready.php etc. files? Or do I have to use a template file (e.g. virtual-page.php)? When I look into Captain Hook  – how do I find the appropriate point to hook into? (/wire/core/ Page.php and loaded()?) Do I need to create/manipulate each field separately (path, title, summary)? Sorry for the long read
       
    • By maxf5
      Hey guys,
      i have some sort of events/campaigns which have a lifespan. To deactivate them i made a checkbox-field called closed and i have to deactivate them manually.
      I would like to put two fields in the template, startdate and enddate, which activate/deactivate that checkbox field automatically.
      Dou you have any idea how to bring that on the run?
    • By Mustafa-Online
      I want to remove "Breadcrumbs" From Some Admin Pages .. for example (Modules/Profile) Pages.
      Aslo: How To Modify Page Headline .. Thanks
      .