Saving page in foreach loop

Hi,
I am using a hook to make some changes to a page, and am looping through some data as part of this. This is the code I have:

'page.create:after' => function ($page) {
        if ($page->template()->name() === 'school') {

          $schoolType = $page->schoolType();
          $blockPages = page($schoolType)->children();

          foreach ($blockPages as $blockPage) {
            $blockName = $blockPage->slug();
            
            foreach ($blockPage->children() as $sectionPage) {
              $sectionName = $sectionPage->slug();

              $schoolKeyTasksField = site()->getSchoolKeyTasksFieldName($blockName, $sectionName);
              $pageKeyTasks = $sectionPage->keyTasks()->yaml();
              $schoolKeyTasks = [];

              foreach ($pageKeyTasks as $keyTask) {

                $schoolKeyTask = $keyTask;
                $schoolKeyTask['questionautoid'] = $schoolKeyTask['autoid'];
                unset($schoolKeyTask['autoid']);
                $schoolKeyTasks []= $schoolKeyTask;

              }

              $page->save([
                $schoolKeyTasksField => Data::encode($schoolKeyTasks, "yaml")
              ]);
            }
          }
        }
      },

When the hook runs, only the last run of the foreach loop is actually saved to the page. I can’t work out why this would be - can I only use the save once in a hook?

If I were you, I would build the array of data inside the loop and then call $page->save() only once.

'page.create:after' => function ($page) {
        if ($page->template()->name() === 'school') {

          $schoolType = $page->schoolType();
          $blockPages = page($schoolType)->children();
          $content    = array();
          foreach ($blockPages as $blockPage) {
            $blockName = $blockPage->slug();
            
            foreach ($blockPage->children() as $sectionPage) {
              $sectionName = $sectionPage->slug();

              $schoolKeyTasksField = site()->getSchoolKeyTasksFieldName($blockName, $sectionName);
              $pageKeyTasks = $sectionPage->keyTasks()->yaml();
              $schoolKeyTasks = [];

              foreach ($pageKeyTasks as $keyTask) {

                $schoolKeyTask = $keyTask;
                $schoolKeyTask['questionautoid'] = $schoolKeyTask['autoid'];
                unset($schoolKeyTask['autoid']);
                $schoolKeyTasks []= $schoolKeyTask;

              }
              $content[$schoolKeyTasksField] = Data::encode($schoolKeyTasks, "yaml");
          
            }
          }
          $page->save($content);
        }
      },

Alternatively, you would have to store the result of $page->save() in a new variable because objects in Kirby are immutable.

That’s great, thanks for the pointer. Just needed to change the last bit to:

$page->save($content);

And then it worked perfectly

Yes, sorry, forgot to remove the array brackets.