Stop execution of a function via hook
Started by Nico Knoll, Jan 14 2012 05:17 PM
11 replies to this topic
#1
Posted 14 January 2012 - 05:17 PM
Hi,
is there a way to stop the execution of a function via hook?
/ Nico
is there a way to stop the execution of a function via hook?
/ Nico
#2
Posted 15 January 2012 - 08:32 AM
Hi Nico
Do you have a more detailed description or a code example of what you're trying to do? Specifically which function you're trying to stop?
Do you have a more detailed description or a code example of what you're trying to do? Specifically which function you're trying to stop?
#3
Posted 16 January 2012 - 02:15 PM
Nico, this is something that is technically possible with the way the hook system is designed, but I've not implemented it yet. The idea behind it was that there would be a 'replace' hook, where you can have your own function completely replace the functionality of a core function, so that the core one is never called. I haven't implemented this because it's not so friendly in an environment where there may be multiple modules hooked to a given function. If one module completely takes over a core function, it alters program flow and the behavior that other modules may be expecting. So I've left it out because I think it's a bit too unpredictable, though may still add it in if there's interest. However, you can achieve the same effect by using an 'after' hook and completely replacing the $event->return value with your own. Not as efficient as replacing the execution too, but much more predictable.
#4
Posted 16 January 2012 - 07:05 PM
@Ryan: I'm using the $event->return way right now, but the problem is that the original function throws a 404 header. (It's because I'm changing the URLs with my module).
#8
Posted 24 January 2012 - 01:50 PM
Nico, this has been added in the latest commit of 2.2. To make use of it, have your hooked function (getPage in your case) do this:
Also your hook obviously must be a 'before' hook in order to replace the original. So you'd init the hook like this:
Unrelated to the above, but another cool addition: I upgraded the hook system so that it will let you set or get hooked function arguments by name rather than just by position. So if you'd hooked into Pages::save, and you wanted to refer to the 'page' argument, you can now do this:
Before you could only do this, having to know what position the argument was in:
You can also set arguments back to the event by name if you want to, i.e.
$event->replace = true; // now original function won't be called $event->return = 'you are now providing the return value';
Also your hook obviously must be a 'before' hook in order to replace the original. So you'd init the hook like this:
$this->addHookBefore('ProcessPageView::execute', $this, 'getPage');
Unrelated to the above, but another cool addition: I upgraded the hook system so that it will let you set or get hooked function arguments by name rather than just by position. So if you'd hooked into Pages::save, and you wanted to refer to the 'page' argument, you can now do this:
$page = $event->arguments('page');
Before you could only do this, having to know what position the argument was in:
$page = $event->arguments[0];
You can also set arguments back to the event by name if you want to, i.e.
$event->arguments('page', $mypage);
#9
Posted 24 January 2012 - 02:47 PM
That's really great to have the arguments by name and not position! Thanks Ryan for the update.
But I'm not quite getting the last one. Maybe a little example could make it more clear?
But I'm not quite getting the last one. Maybe a little example could make it more clear?
@somartist | modules created | support me, flattr my work flattr.com
#10
Posted 24 January 2012 - 02:54 PM
Yes, great additions.
Soma, in the example Ryan is changing original page with different/modified one.
Soma, in the example Ryan is changing original page with different/modified one.
#11
Posted 24 January 2012 - 04:00 PM
But I'm not quite getting the last one. Maybe a little example could make it more clear?
Antti's right about what that example is doing, but let me do another. Lets say we've hooked in before $session->redirect(). If I go look at the function definition in /wire/core/Session.php, I can see it has two arguments: $url and $http301. So lets say I want to hook into that and automatically add a GET variable to every redirected URL, like "url.com/path/?is_redirected=1", I'd do this:
public function hookSessionRedirect(HookEvent $event) {
$url = $event->arguments('url'); // get the existing value
$url .= (strpos($url, '?') === false ? "?" : "&") . "is_redirected=1";
$event->arguments('url', $url); // set the new value that gets sent to $session->redirect
}
Btw, there is some overhead in using the argument names as opposed to the position (it involves using Reflection), so in most cases I think it's still better to use the argument position rather than the name. But have wanted to make both options available because I think some people will find it more straightforward to to use the argument names... and it no doubt makes code examples more readable.
#12
Posted 25 January 2012 - 09:42 AM
Wow, looks nice. Have to try PW 2.2 in the next days. I didn't do it until now because I thought I could wait for the final release
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users













