Set all subpages to same status as parent

Hello - I am trying to figure out a way to set the child pages of a parent to the same status via the page.changeStatus:after hook but I can’t figure out the logic. Can someone point me in the right direction?

return [
  'hooks' => [
    'page.changeStatus:after' => function ($page) {
      if($page->status() == 'listed') {
        $page->children()->changeStatus('listed');
      }
    }
  ]
];

You have to loop through the children and call changeStatus on a single page object, not on the collection.

Somthing like:

return [
  'hooks' => [
    'page.changeStatus:after' => function ($page) {
      if($page->status('listed')) {
        foreach($page->children() as $item) {
          $item->changeStatus('listed');
        }
      }
    }
  ]
];

Yes, but note that you have to use named parameters $newpage/$oldPage, not $page:

    'hooks' => [
        'page.changeStatus:after' => function ($newPage, $oldPage) {
            if ($newPage->status() === 'listed') {
                foreach ($newPage->children() as $item) {
                    $item->changeStatus('listed');
                }
            }
        }
    ]

Note that you also can’t pass listed as argument to the status() method.

This is an old post now so apologies… but do I need to impersonate Kirby for this to work?

my code is:

    'page.changeStatus:after' => function ($newPage, $oldPage) {
      $kirby = kirby();
      $kirby->impersonate('kirby');
      if ($newPage->status() === 'listed') {
        foreach ($newPage->children() as $item) {
          $item->changeStatus('listed');
        }
      }
    }

I don’t seem to be able to get it to wotk.

The code should work, but note that if the children are still drafts, you have to modify the code slightly:

  foreach ($newPage->childrenAndDrafts() as $item) {
          $item->changeStatus('listed');
        }

You don’t need the impersonate() bit, because you usually have a logged-in user when the hook is called.

That was exactly what was happening, thank youyou. The children were indeed drafts. If I also wanbted to target all childdren and grandchildren and grandchildren’s children etc. is that possible? I tried:

foreach ($newPage->childrenAndDrafts()->index(true) as $item) {
  $item->changeStatus('listed');
}

without success.

This should work:

foreach ($newPage->index(true) as $item) {
  $item->changeStatus('listed');
}