Chaining multiple hooks

Hi,

I’m implementing a editorial approval process using hooks. In one scenario I want to reset already given approvals and restart the approval process. The code for the hook looks like this:

kirby()->hook(['panel.page.update'], function($page, $oldPage = null) {

  // Start the process if all approvers are set and a content creator edits the page
  if ( $page->approver()->isNotEmpty()
    && $page->author()->isNotEmpty()
    && $page->approvecontent()->bool()
    && $page->approvelanguage()->bool()
    && $this->role() == 'contentcreator' ) {

    // Reset the approvals
    $newPage = $page->update(array(
      'approvecontent'  => '',
      'approvelanguage' => ''
    ));

    // Trigger an update event to restart the approval process
    $this->kirby()->trigger('panel.page.update', $newPage);

  }

});

The hook executes correctly and updates the page, however the new hook is not triggered. Is this by design? Is there any way to trigger a new hook after the current one is executed?

Thank you,
Georg

You are using $this out of context, so this code won’t work.

Correct:

kirby()->trigger('panel.page.update', $page);

Thank you. I already tried this one and it is also not working. The hook is not triggered.
Here it says that this is happening by design? But the suggested code
kirby()::$triggered = array();
is also not working inside the hook.

Yes, the problem is that such nested hooks might easily end up in an endless loop if you are not careful.

Yes, I try to be careful :wink:
So there is no way to trigger a hook from inside a hook? And my example from above is expected to not work?

I think this is not possible, at least it does not work. But in your code above, the second update hook wouldn’t do anything anyway (unless your code is incomplete).

Yes, my code is not complete. I’ve other hooks in other files that together build the process, so one of them should fire, wen I trigger a new hook with kirby()->trigger('panel.page.update', $page);
Does this also mean, that if I have multiple hooks (in different files and plugins) that are working on the same action, only one of them (the first?) fires and the others are not executed?

Yes, I think so, see also this issue: https://github.com/getkirby/panel/issues/1006

You are correct @texnixe! I was about to mention that issue.

Under the hood, Kirby keeps a record of which hooks have been called during each session and skips the duplicate ones.

You can work around that issue.
I had to do this as well in one of my plugins.

// Reset previously triggered hooks
kirby()::$triggered = array();

But you need to make sure your code does not end up in an endless loop!

Does this also mean, that if I have multiple hooks (in different files and plugins) that are working on the same action, only one of them (the first?) fires and the others are not executed?

Kirby will execute all registerd hooks. But kirby will execute all of them only once!

1 Like

Thank you, this workaround seems fine for me, otherwise I would need to re-think the whole architecture … :wink:
However, this seems not to work in the context of the hook:
[22-Nov-2017 17:08:42 Europe/Berlin] PHP Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM) in /Users/georgobermayr/Documents/Git/my-site/site/plugins/workflow/hooks/resetApprovals.php on line 28
Do you have any idea if it is possible to access $triggered inside of a hook?

I think Lukas meant this: kirby::$triggered   :wink:

Thank you both. The syntax with kirby::$triggered didn’t produce a syntax error, but from my perspective it also didn’t work when executed from inside a hook :frowning:
I now endend with a solution that relies on the order in which I include the different hook functions. With that I no longer need to trigger the hook again, because it already runs after the reseting took place in the first hook. I would say that this is not an ideal solution and I hope this is solid when we further scale the application but for now it works :wink: