I have a product blueprint with an external ID field for the corresponding product in Stripe. I wrote a page update hook to handle the Stripe side. The problem occurs at the very last step when I need to update the local product with that field, I’m unable to save it
If I simply use $page->update( [$field => $fieldData] ); I get this error
Worse still, it completely wipes the saved content file after that and I lose everything.
I tried using impersonate with either the authenticated user or the superuser kirby instead to see if it helps, I get this instead (and it also wipes the content file after)
Hook config:
'hooks' => [
'page.update:after' => function ( $newPage, $oldPage = null ) {
$updateHandler = new PageUpdateHandler();
$updateHandler->handle( $newPage, $oldPage );
},
],
Update code in the handler: (complete code here)
kirby()->impersonate( kirby()->user() ); // with or without this part
$product->parent()->update(['external_id' => $productStripeId]);
Template: (full template here)
external_id:
type: text
label: External Price ID
help: Auto-generated ID from payment system, leave blank
translate: false
I should add that if I update the field value manually in the panel UI it works fine, something about the programmatic update in the backend I can’t figure out
Hard to tell if and what is going wrong. To start debugging this, I would first try a manual update (without any impersonated user) directly from the hook:
'hooks' => [
'page.update:after' => function ( $newPage, $oldPage = null ) {
$newPage->update(['external_id' => 'somevalue']);
},
],
If that works, debug your code step by step.
I think I found the issue, this only happens when I’m updating two fields on the page through the hook in one save action. If I try to perform one update at a time it works, if both fields are modified and need to be saved then this happens.
Is there a way to “commit” the first change when I call update([]) before I invoke it a second time later on ?
Objects are immutable in Kirby. So say you do
$page->update();
And want to update that object again later, you first need to store it in a variable.
$page = $page->update();
Then use the new page for the next update step.
I’ve just tried that but it still won’t allow me the second update.
The second update is updating a field on a nested YAML structure on the main object, and I’m passing the $page variable to a utility function to perform that update. Is it possible any of that prevents further updates?
I’ve also tried fetching a new page instance before the second update like this page(‘my-page-name’)→update(['subfield' => ‘value’]); to no effect