getkirby / kirby

Kirby's core application folder
https://getkirby.com
Other
1.32k stars 168 forks source link

Using `$page->blueprint()->sections()` in a hook breaks the frontend #2575

Closed medienbaecker closed 2 years ago

medienbaecker commented 4 years ago

Describe the bug
Using $page->blueprint()->sections() in e.g. a route:after hook breaks all kind of things in the frontend. For example it corrupts the translations and corrupts the page's children().

To Reproduce
Add something like this to the site/config/config.php:

'hooks' => [
  'route:after' => function ($route, $path, $method, $result) {
    $uid = explode('/', $path);
    $uid = end($uid);
    $uid = str_replace('+', '/', $uid);
    $page = kirby()->page($uid);
    if (!$page) {
      $page = site()->homePage();
    }
    $test = $page->blueprint()->sections();
  }
]

All I'm doing is putting the sections of the page blueprint in to a $test variable. Somehow it breaks all kinds of stuff instead:

hook-bug

Expected behavior
Nothing but a variable with the blueprint sections.

Kirby Version
3.3.5

Additional context
I made a plainkit with a simple plugin so you can test the issue: Hook-Bug.zip

afbora commented 2 years ago

After two years 😱 I've tracked the issue and I've an clue about the issue.

When call the $page->blueprint()->sections() code, following line running and broke the translation.

$content  = $this->model->content()->toArray();

https://github.com/getkirby/kirby/blob/3.6.3/config/sections/fields.php#L15

Possible solution/idea

As workaround I've fixed the issue with passing current language. I'm not sure about stable solution but this may be give you an idea about solution.

$lang     = $this->model->kirby()->language() ?? null;
$content  = $this->model->content($lang)->toArray();
bastianallgeier commented 2 years ago

@afbora you are a genius :)

distantnative commented 2 years ago

Sounds indeed like a good fix. Can we get it in a PR? Ideally we would be able to come up with a unit test that reproduces the buggy behavior before and passes with the fix, but maybe that's hard to do.

bastianallgeier commented 2 years ago

Looking at it again, it should be:

$lang = $this->model->kirby()->languageCode();
$content = $this->model->content($lang)->toArray();
bastianallgeier commented 2 years ago

✅