Author acces to only the pages they've created

Hello to all,

I’m trying to use a before hook inside the panel in order to prevent acces to specific pages for specific author.

The idea is that the authors can acces only the pages they’ve created in three differents sections :

0_events
    1_first-event // Author-John
    2_second-event // Author-John
    2_third-event // Author-Jim

    // Here Author-Jim should only be able to acces or edit the third event

1_articles
    1_first-article
    2_second-article
    2_third-article

2_companies
    1_first-company
    2_second-company
    2_third-company

I tried the solutions proposed in those threads :

This one work on every pages of the site including main pages (events, articles, companies).

'route:before' => function ($route, $path, $method) {
        if (Str::startsWith($path, 'api/pages/') && $method == 'GET') {
            $pagePath = str_replace('+', '/', str_replace('pages/', '', $route->arguments()[0]));
            $page = page($pagePath);
            $user = kirby()->user();
            if ($page && $user) {
                if ($user !== $page->author()->toUser()) {
                    throw new Exception('You cannot access this page');
                }
            }
            
        }
      },

I’m thinking there’s a way for affecting only the children pages but my knowledge in php don’t go that far.

I tried adding children to Str::startsWith($path, 'api/pages/children') && $method == 'GET') with no luck. I’m guessing there’s also some configuration to be made in the $pagePath variale.

Thanks in advance for any kind of input or help.

Théo.

I have recently tested overriding the isReadable() method in a page model. To me that seems to be the most effective way at the moment.

Need to go hunting now but will come back to this later.

Edit: I found the example:

class NotePage extends Page
{
  
    public function isReadable(): bool
    {
        static $readable = [];

        $template = $this->intendedTemplate()->name();

        if (isset($readable[$template]) === true) {
            return $readable[$template];
        }
        if ($this->author()->toUser() === kirby()->user() || kirby()->user()->role()->name() === 'admin') {
            return true;
        }
        return false;

    }
}

Edit 2: There’s also this plugin worth checking out:

Thank you ! I’ll have a look at the method. well you’re so fast !
I’m trying the method… oh and the plugins.
With all this I’m sure to find a solution.
Thanks again ! I’ll come back later with updates.

After some testing and reading the doc, I’m struggling to understand how to use the page method, it’s probably way up my knowledge.

I’ve created a page_methods plugin with the example code.
But at this stage I’m clueless in how to use the class, is it in a blueprint ?

<?php

class NotePage extends Page
{
  
    public function isReadable(): bool
    {
        static $readable = [];

        $template = $this->intendedTemplate()->name();

        if (isset($readable[$template]) === true) {
            return $readable[$template];
        }
        if ($this->author()->toUser() === kirby()->user() || kirby()->user()->role()->name() === 'admin') {
            return true;
        }
        return false;

    }
}

Kirby::plugin('my/page-methods', [
    'pageMethods' => [
        'publication' => 'isReadable' // random testing 
    ]
]);

btw: Sylvain’s plugin is great but not for this situation.

The class is a page model, so you have to do this on a page type basis, you cannot use page methods to override native methods.

The example refers to children of the Starterkits notespage, which use thenote` blueprint/template.

If your events page children use the event blueprint, you would have to create an EventPage class in in this class, declare the isReadable() method. Then do the same for each page type.

1 Like

Thank ! Works great, looks realy nice :smiling_face_with_three_hearts: I learned something today :tada: !

In case someone else step by; on your first reply you said :
I have recently tested overriding the isReadable() method in a page method. Is it page model what you were intented to say?

Thank again for your help!

Yes, of course! :upside_down_face: