Nico Knoll Posted January 14, 2012 Share Posted January 14, 2012 Hi, is there a way to stop the execution of a function via hook? / Nico Link to comment Share on other sites More sharing options...
Pete Posted January 15, 2012 Share Posted January 15, 2012 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? Link to comment Share on other sites More sharing options...
ryan Posted January 16, 2012 Share Posted January 16, 2012 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. Link to comment Share on other sites More sharing options...
Nico Knoll Posted January 17, 2012 Author Share Posted January 17, 2012 @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). Link to comment Share on other sites More sharing options...
ryan Posted January 17, 2012 Share Posted January 17, 2012 I understand -- I think that's a good reason for us to add a replace hook. For my own testing when implementing this, can you tell me which function it is that you are hooking into? Link to comment Share on other sites More sharing options...
Nico Knoll Posted January 17, 2012 Author Share Posted January 17, 2012 $this->addHook('ProcessPageView::execute', $this, 'getPage'); (See the rest of my code at GitHub if you need it ) Link to comment Share on other sites More sharing options...
ryan Posted January 18, 2012 Share Posted January 18, 2012 Thanks, I'll add this capability to the hooks API. Link to comment Share on other sites More sharing options...
ryan Posted January 24, 2012 Share Posted January 24, 2012 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: $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); 1 Link to comment Share on other sites More sharing options...
Soma Posted January 24, 2012 Share Posted January 24, 2012 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? Link to comment Share on other sites More sharing options...
apeisa Posted January 24, 2012 Share Posted January 24, 2012 Yes, great additions. Soma, in the example Ryan is changing original page with different/modified one. Link to comment Share on other sites More sharing options...
ryan Posted January 24, 2012 Share Posted January 24, 2012 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. 1 Link to comment Share on other sites More sharing options...
Nico Knoll Posted January 25, 2012 Author Share Posted January 25, 2012 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 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now