processwire-issues icon indicating copy to clipboard operation
processwire-issues copied to clipboard

Hooks on unpublished and off-status repeater items are executed when saving the repeater field and noHooks is true

Open jlahijani opened this issue 3 months ago • 1 comments

Assume the following code:

// init.php
wire()->addHookAfter('Pages::saved', function(HookEvent $event) {
  $page = $event->arguments('page');
  if($page->template->name!='repeater_order_line_items') return;
  echo "running the hook!";
});

// elsewhere in my codebase

$order = $pages->get(1234);

// unpublish the repeater items
foreach($order->order_line_items as $order_line_item) {
  $order_line_item->addStatus(Page::statusUnpublished);
  $order_line_item->removeStatus(Page::statusOn);
  $order_line_item->save(['noHooks'=>true]);
}

// now let's save the overall order_line_items field and make sure to prevent hooks
// remember, using noHooks=>true on the save method of a page is technically not the "correct" way to do it
// but it doesn't matter; either of these will still make the hooks fire when they shouldn't!
// https://github.com/processwire/processwire-issues/issues/1405#issuecomment-3152818716

// doesn't matter which one you use... the hooks still fire since the pages were unpublished and status turned off
$order->save('order_line_items', ['noHooks'=>true,'quiet'=>true]);
wire('pages')->___saveField($order, 'order_line_items', ['noHooks'=>true,'quiet'=>true]);

So as you can see above, in that scenario, the hooks will fire when they shouldn't. This drove me nuts.

Related to #1405

jlahijani avatar Sep 02 '25 21:09 jlahijani

@jlahijani The noHooks option refers to the page being saved, $order in your example. Individual repeater pages are separate pages where the save is initiated by FieldtypeRepeater, which does not use a noHooks option. Your $order_line_item->save(['noHooks' => true ]); shouldn't call hooks. But the following $order->save() or $page->saveField() should still trigger your Pages::saved hook if FieldtypeRepeater is saving any repeater items.

ryancramerdesign avatar Sep 18 '25 15:09 ryancramerdesign