Robin S Posted January 8, 2017 Posted January 8, 2017 I'm hoping someone might explain the difference between addHookProperty() and addHookMethod() and when you would use one over the other. One of the things I find confusing is that the docs for addHookMethod() say that it is an alias for addHook(), yet the example given for addHook() in the Hooks documentation is the same is the example given for addHookProperty() in the new API reference.
kongondo Posted January 9, 2017 Posted January 9, 2017 (edited) They look quite different to me (the examples). addHookProperty does just that; adds a property. The property is available to the object you are attaching it to. You can't pass it any arguments to manipulate what it returns. addHookMethod/addHook allows you to add a method/function to an existing class or object. You can have the method you've 'created' accept arguments that inform the method's logic. Although the examples are similar, they are not identical. addHookProperty example. We cannot change/alter the output since this is a property (variable) unless we 'manually' assign it a new value // Accessing the property (from any instance) echo $page->lastModifiedStr; // outputs: "10 days ago" addHookMethod/addHook example. We can add as many arguments as we want to lastModified() since it is a method. In the example in the docs, the method accepts only one boolean argument. This allows us to alter what lastModified() returns. Hence, it offers more flexibility. echo $page->lastModified(true); // returns "10 minutes ago" echo $page->lastModified(false); // returns "2013-05-15 10:15:12" echo $page->lastModified(); // returns "2013-05-15 10:15:12" That's my understanding of it anyway... Edited January 9, 2017 by kongondo fixed wrong url 4
Robin S Posted January 9, 2017 Author Posted January 9, 2017 Thanks. I'm sure I'm missing something here, but it seems like addHookMethod() can do everything that addHookProperty() can plus it can optionally take arguments. In the Hooks docs there is this example for addHook(), aka addHookMethod(): public function init() { $this->addHook('Page::lastModified', $this, 'lastModified'); } public function lastModified($event) { $page = $event->object; $event->return = wireRelativeTimeStr($page->modified); } echo $page->lastModified(); // outputs "10 minutes ago" And then in the addHookProperty() API reference there is virtually the same example: // Adding a hook property $wire->addHookProperty('Page::lastModifiedStr', function($event) { $page = $event->object; $event->return = wireDate('relative', $page->modified); }); // Accessing the property (from any instance) echo $page->lastModifiedStr; // outputs: "10 days ago" So the addHook() example could alternatively be added with addHookProperty(). But if addHook()/addHookMethod() can "do more" than addHookProperty() thanks to the ability to pass in arguments, in what circumstances would you want to use addHookProperty()? 1
kongondo Posted January 9, 2017 Posted January 9, 2017 4 minutes ago, Robin S said: So the addHook() example could alternatively be added with addHookProperty(). But if addHook()/addHookMethod() can "do more" than addHookProperty() thanks to the ability to pass in arguments, in what circumstances would you want to use addHookProperty()? Exactly . Had the same thoughts. On the face of it, it would seem like one is just an extension of the other (see also this example under addProperty - the one that returns an intro of a body copy). However, the same question could be asked when developing a class (PHP or otherwise). When should I use a class property versus a class method? If we are going to use something repetitively, especially when some degree of flexibility is required, we go with a method. If we need to stick with some value, we might as well use a property. So, I guess, IMO, it is about what best works for your present needs. 2
Robin S Posted January 9, 2017 Author Posted January 9, 2017 2 minutes ago, kongondo said: Exactly . Had the same thoughts. On the face of it, it would seem like one is just an extension of the other One difference that just occurred to me is that the property may used in a selector but the method may not. So in the examples from my last post I could do... $results = $pages->find("lastModifiedStr=10 days ago"); ...but not... $results = $pages->find("lastModified=10 minutes ago"); Is that right?
kongondo Posted January 9, 2017 Posted January 9, 2017 (edited) Unless I misunderstood you, I don't think either would work since selectors at their basic level query the database. Both code should throw an exception that field 'lastModified' and field 'lastModifiedStr' do not exist. In this particular case, I don't see how an in-memory search would be helpful (or even feasible?). Edited January 9, 2017 by kongondo clarity 1
Robin S Posted January 9, 2017 Author Posted January 9, 2017 28 minutes ago, kongondo said: Unless I misunderstood you, I don't think either would work since selectors at their basic level query the database. Both code should throw an exception that field 'lastModified' and field 'lastModifiedStr' do not exist. In this particular case, I don't see how an in-memory search would be helpful (or even feasible?). You're absolutely right that neither would work with $pages->find() - I didn't think that through. But I think it should be possible to use the property in an in-memory selector, like: $results = $some_pagearray->find("lastModifiedStr=10 days ago"); Trouble is I can't test this as I can't get the code example in the API reference for addHookProperty() to work. Does it work for you? For me the hook never fires and I just get NULL for $page->lastModifiedStr. The same hook code works fine when in addHook() or addHookMethod() and called with $page->lastModifiedStr().
kongondo Posted January 9, 2017 Posted January 9, 2017 (edited) It works for me (all work). Tested in a template file (added at the very top - PW 2.8). I'd also tried an in-memory selector but it was returning the wrong result. // $wire as a variable $wire->addHookProperty('Page::lastModifiedStr', function($event) { $page = $event->object; $event->return = wireDate('relative', $page->modified); #$event->return = $page->children->last()->title;// just a test; works }); // Accessing the property (from any instance) echo $page->lastModifiedStr; // outputs: "1 month ago" // wire as a function wire()->addHookProperty('Page::intro', function($event) { $page = $event->object; $intro = 'Hello World'; $event->return = $intro; }); echo $page->intro;// outputs "Hello World" Edited January 9, 2017 by kongondo in-memory selector actually worked 1
Robin S Posted January 9, 2017 Author Posted January 9, 2017 4 hours ago, kongondo said: It works for me (all work). Tested in a template file (added at the very top - PW 2.8). I'd also tried an in-memory selector but it was returning the wrong result. Thanks. I tried all manner of things and just couldn't get it working in one test environment - but there is a lot of stuff going in that environment so probably a conflict of some sort. Tried it in a cleaner environment and it works as expected. I can confirm that properties added by addHookProperty() can be matched by an in-memory selector: $basic_pages = $pages->find("template=basic_page"); $result = $basic_pages->find("lastModifiedStr=2 months ago"); So that could be a compelling reason to prefer addHookProperty() over addHookMethod() depending on the circumstances.
LostKobrakai Posted January 9, 2017 Posted January 9, 2017 Properties are also useful for the places, where one might use the result in any getMarkup() calls (e.g. what to show in the page list). $pageArray->explode('<a href="{editUrl}" target="_blank">{lastModifiedStr}</a>'); 2
kongondo Posted January 9, 2017 Posted January 9, 2017 Just to clarify that RE in-memory selector, it actually also works for me. I was using the 'wrong' selector in my $pages->find() .
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