Jump to content

Pages::saved hook and preventing infinite looping?


Recommended Posts

I don't remember if I've dealt with this properly before, or if I just used setAndSave to avoid the issue.  But it brings up a question on how to do it the right way.

My overall question is how do you properly attach a Pages::saved hook and again save the same page without causing an infinite loop?

Let's say I have a hook like this:

// works, but must setAndSave each field; doesn't seem ideal?
wire()->addHookAfter("Pages::saved(template=basic-page)", function(HookEvent $event) {
  $p = $event->arguments('page');
  $p->setAndSave('title', time());
});

That will work fine if I save a page or multiple pages using the basic-page template.  OK.

But if I want to save a bunch of different fields instead of just title, what is the correct way to do it?  These will cause an infinite save loop:

// causes infinite save loop
wire()->addHookAfter("Pages::saved(template=basic-page)", function(HookEvent $event) {
  $p = $event->arguments('page');
  $p->title = time();
  $p->some_other_field = 'foo';
  $p->save();
});

// this also causes infinite save loop
wire()->addHookAfter("Pages::saved(template=basic-page)", function(HookEvent $event) {
  $p = $event->arguments('page');
  $p->title = time();
  $p->some_other_field = 'foo';
  $p->save(['title', 'some_other_field']);
});

If I remove the hook, it will save the page, but since the hook gets removed, it will only apply to the first page:

// fixes infinite loop but hook gets removed; see below
wire()->addHookAfter("Pages::saved(template=basic-page)", function(HookEvent $event) {
  $event->removeHook(null); // remove the hook!
  $p = $event->arguments('page');
  $p->title = time();
  $p->some_other_field = 'foo';
  $p->save();
});

// only the first page will run the hook since it is removed
foreach($pages->find("template=basic-page") as $p) {
  $p->save();
}

 

Link to comment
Share on other sites

OK I answered my own question.  I need to use noHooks:

wire()->addHookAfter("Pages::saved(template=basic-page)", function(HookEvent $event) {
  $p = $event->arguments('page');
  $p->title = time();
  $p->save(['noHooks'=>true]);
});

 

Just now, dynweb said:

Did you try this?

$p->save(['noHooks' => true]);

 

You beat me by 5 seconds!

  • Like 2
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...