Hook can't modify block content "currently edited by another user"

Hello!

Im trying to modify the content of some blocks in an 'page.update:after’ hook. The problem is that when ever I save I get the message “This content is disabled for you as it is currently edited by another user”, which is me/the hook.

This is what i’m currently working with:

'page.update:after' => function ($newPage) { 
    $blocks = $newPage->mediaContent();

    if ($blocks->isNotEmpty()) {
        $hasChanges = false;
        $updatedBlocks = $blocks->toBlocks()->map(function ($block) use (&$hasChanges) {

            if ($block->type() !== 'video') {
                return $block;
            }
            
            // Check if we need to fetch Vimeo data
            if ($block->height()->isNotEmpty() || 
                $block->url()->isEmpty() || 
                !str_starts_with($block->url()->value(), 'https://vimeo.com')) {
                return $block;
            }
            
            $response = Remote::get('https://vimeo.com/api/oembed.json?width=1920&url=' . $block->url());
            
            if ($response->code() !== 200) {
                return $block; // API call failed, return unchanged
            }
            
            $content = JSON::decode($response->content());
            
            // Check if we got the required data
            if (!isset($content['height']) || !isset($content['width'])) {
                return $block; // Missing data, return unchanged
            }
            
            $height = $content['height'];
            $width = $content['width'];
            $blockContent = $block->content()->toArray();
            
            $hasChanges = true;
            
            // Return updated block
            return new Kirby\Cms\Block([
                'content' => array_merge($blockContent, [
                    'height' => $height,
                    'width' => $width
                ]),
                'type' => $block->type(),
                'id' => $block->id()
            ]);
        });

        if ($hasChanges) {
            $kirby = kirby();
            $kirby->impersonate('kirby');
            
            $newPage->update([
                'mediaContent' => json_encode($updatedBlocks->toArray())
            ]);
        }
    }
}

Feels like I’m missing the last piece to this puzzle. Is there anyone who have done something similar without this permission conflict?

So the problem for me was that I where using the super user ‘kirby’, just using update() without it runs as it should. This cookbook article was also very helpful to understand how it should be setup.

Leaving my current working draft here if anyone has use for it in the future.


$blocks = $newPage->mediaContent();

if ($blocks->isNotEmpty()) {
    $hasChanges = false;
    $new = [];


    foreach ($blocks->toBlocks() as $block) {
        // Store the current values
        $old = $block->toArray();

        if ($block->type() === 'video') {
            if (empty($old['content']['height']) && 
                !empty($old['content']['url']) && 
                str_starts_with($old['content']['url'], 'https://vimeo.com')) {
            
                $response = Remote::get('https://vimeo.com/api/oembed.json?width=1920&url=' . $old['content']['url']);
            
                if ($response->code() === 200) {
                    $content = JSON::decode($response->content());
                    
                    if (isset($content['height']) && isset($content['width'])) {
                        // Manipulate the desired values in the content array
                        $old['content']['height'] = $content['height'];
                        $old['content']['width'] = $content['width'];
                        $hasChanges = true;
                    }
                }
            }
        }

        // Add block to the new array (whether changed or not)
        $new[] = new Kirby\Cms\Block($old);
    }

    if ($hasChanges) {

        // Create the new Blocks object from the array of blocks
        $blocks= new Kirby\Cms\Blocks($new);
        
        $newPage->update([
            'mediaContent' => $blocks->toArray()
        ]);
    }
}