Updating page content in a controller

This seems to be a more general issue, unrelated to Uniform: Updating page content in a controller - #5 by nilshoerrmann

I’m using Uniform for the first time to handle user input. In my specific use case, a members area, I’d like to store content back to Kirby and so I created a custom action:

<?php

namespace Uniform\Actions;

class StoreAction extends Action
{
    private $page = null;

    public function perform()
    {
        $id = $this->form->data('id');

        if ($id) {
            $this->page = page($id);
        }

        if ($this->page) {
            $this->form->forget('id');
            $this->page->update($this->form->data());
        } else {
            $this->fail('Die gegebene Seite existiert nicht.');
        }
    }
}

There is also a guard to make sure the user is logged into Kirby:

<?php

namespace Uniform\Guards;

class UserGuard extends Guard
{
    public function perform()
    {
        if (!kirby()->user()) {
            $this->reject();
        }
    }
}

And this is my controller:

<?php
use Uniform\Form;

return function ($kirby, $page) {
    $form = new Form([
        // some validation rules
    ]);

    if ($kirby->request()->is('POST')) {
        $form->userGuard()->storeAction();
    }

    return compact('form');
};

So far, so good, but as soon as I post my form my template stops working complaining that global variables like $kirby or $page no longer exist:

Undefined variable: kirby
/site/snippets/site.php line 2

<?php
if (!$kirby->user() && !$page->is('login')) {
    go('/login');
} ?>

// and the template goes on …

What can I do about this?

My guess is this has to do with updating the current page that Kirby is currently trying to display but I’m not sure. I can make this work by adding $this->page->go() after updating it but that way I’m loosing the Uniform context (form data, success information).

/cc @mzur

Try:

$this->page =  $this->page->update($this->form->data());

That sadly doesn’t change anything.

But that’s the exact line causing the error. If I uncomment it, there will be no error – but of course nothing is stored as well.

So this doesn’t seem to be related to Uniform at all. It also happens when I perform a page update in my controller directly. After posting, all global variables are no longer available in my snippets. They are still accessible in my templates but no longer in my snippets.

@nilshoerrmann if I understand it correctly, in 3.4.0 we have new feature that you can pass modified kirby core objects ($site, $pages, $page, $kirby) from controller to view like that;

return function($kirby, $page) {
    $page = $page->update(['test' => uniqid()]);

    return [
        'page' => $page
    ];
};

I could track this down to the page’s blueprint. I’ve got this definition on top of the file:

title: Ereignis
num: '{{ page.start.toDate("Ymd") }}'

If I uncomment the num part everything works as expected. I don’t understand why though …

@ahmetbora That’s a great feature. Still I don’t understand why all global objects are unset in the first place.

May be num issue is related with #2581 ? :thinking:

If you mean in the controller, we don’t unset global objects there. We were merging global objects with data from the controller. In the last version, we allowed the user to send a global object with safely.

The problem is, when I update the current page in the controller, all global object are unset in the snippets but not the templates. It’s caused by this line in my blueprint:

num: '{{ page.start.toDate("Ymd") }}'

If I remove the custom num setting, I can update my current page without breaking the global objects in my snippets.

This does not make sense to me at all. How can the data be lost in the snippets and how can the blueprint num setting be the root cause for this?

I tested it, but I couldn’t find the error. Can you share pieces of code where I can get the error please? Blueprint, controller, snippet, etc…

In the current Starterkit, go to the note blueprint and change num: date to num: '{{ page.date.toDate("Ymd") }}'.

Then create a controller note.php:

<?php

return function ($page) {
    $page->update();
};

Try to access /notes/exploring-the-universe.

I reproduced too :slightly_frowning_face: Could you create new issue please?

Here we go: https://github.com/getkirby/kirby/issues/2737

1 Like