Jump to content

addHookProperty() versus addHookMethod()


Robin S
 Share

Recommended Posts

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.

 

Link to comment
Share on other sites

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 exampleWe 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 by kongondo
fixed wrong url
  • Like 4
Link to comment
Share on other sites

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()?

  • Like 1
Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by kongondo
clarity
  • Like 1
Link to comment
Share on other sites

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().

Link to comment
Share on other sites

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 by kongondo
in-memory selector actually worked
  • Like 1
Link to comment
Share on other sites

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.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...