Updating structure field in page.update:after hook

Hi, Iā€™m trying to add a unique id to a structure field after the page is saved. However, it keeps throwing the following error in a modal after saving:

The JSON Preformatted text response from the API could not be parsed. Please check your API connection.

Hereā€™s the hook:

if ($newPage->intendedTemplate() == "projects") {
		$projects = $newPage;

		// Locations
		$locationcount = $projects->locationcount()->int();
		$locations = $projects->locations()->yaml();

		foreach($locations as &$item) {
			if (!isset($item["id"]) || !$item["id"]) {
				$item["id"] = $locationcount;
				$locationcount += 1;
			}
		}

		$projects->update([
			'locations' => Data::encode($locations, "yaml"),
			'locationcount' => $locationcount
		]);

Maybe itā€™s the typo ā€œ&$itemā€ :stuck_out_tongue:

Is the Id field disabled in your blueprint?

The code works flawlessly in my environment.

Or is there anything else in your code that might interfere.

@REH, no, the & is ok, it means that the variable is passed by reference: http://php.net/manual/en/language.references.pass.php

What is your Kirby version?

The id field is a basic text field and not disabled. Thereā€™s nothing else happening with hooks and if I disable the hook, the page saves without any errors. I just updated Kirby to 3.0.2.

What else could interfere?

Hereā€™s the structure field:

locations:
        label: Locations
        type: structure
        sortBy: en
        translate: false
        fields:
          en:
            label: EN
            type: text
            required: true
          nl:
            label: NL
            type: text
            required: true
          id:
            type: text

Ok, I only tested in a single language Starterkit. Let me see if it makes any difference in a multilang installation.

Well, a new test in a multilang installation was also successful.

Does this happen on a remote host or in your local environment? Do you get any other errors in your console, maybe?

Ups, that was the only part looking incorrect to meā€¦
But thanks @texnixe, learned something new today :slight_smile:

1 Like

Itā€™s difficult to test it on the remote server at the moment because the websiteā€™s already live.

Hereā€™s the console:
33

Found out something interesting, Iā€™ve removed a large part of the content and it worked. I canā€™t find out what partā€™s causing it exactly though.

The content came from the live server and itā€™s quite a lot, too much too ask the client to reenter. Could some kind of special character cause it?

Hm, I canā€™t tell, but could of course be, you never know what happens when you copy text from Word, for example, that then renders the JSON invalid.

What if you add the removed content again? Have you checked to copy the content into a text editor that shows invisible characters?

Or have you tried to re-add the content after saving it in a text editor that likely removes those characters?

Iā€™ve tried to save the page with batches of the content present in the content file +/-10% each time to find an item/character that causes the error. No errors, for none of the content. But when all the content is present, it throws the error. Could it be a timeout, thereā€™s a lot of content and saving takes quite a while.

Can you see in the network tab (called like that in firefox, maybe similar in your browser) what is actually sent as response to the panel?

And is all that content stored in the structure field, so that the hook has to run through thousands of entries?

Instead of using $projects->update() you probably need to use $projects->save(). Otherwise you will end up in an endless loop.

That did the trick! I donā€™t know why though, because ->update() does work when thereā€™s less content in the page.

Yes, everythingā€™s saved in the structure field and there are about 150 items in it.

Iā€™ll see what it sends.

While this makes complete sense, I am wondering why the hook works with some text and with some it doesnā€™t?

Here an old issue for some context.

Not directly the issue but I called the custom method in a hook.

Browsing through the network tab ā†’ response while using ->update() I can see that php returns Fatal error: Maximum execution time.... which is causing the JSON error. ->save() is probably faster and not causing the fatal error.

Interesting, but I thought that the hook was not triggered again from a $page->update()within a hook. If that was the case, wouldnā€™t the same hook with less entries run into the same issue, @lukaskleinschmidt? Trying to understandā€¦

If I understand Bastians answer in the issue posted above correctly, it is not an infinite loop with the update hook calling itself but somewhere in the validation process.
Would be interesting to know what causes itā€¦a lot of text? a lot of items?

I am wondering why the page is so slow in general. It takes about 12 seconds to load the page. The page tab consists only of a few structure fields with +/- 150 items in total. The page on the front-end does load fast without caching.

Loading takes +/- 12 seconds.
Saving takes +/- 22 seconds.
Updating takes 30+ seconds.

p.s. Iā€™ll be able to respond again tomorrow morning