Problem with Controller and Session

Hi there,

I’m having problems with a controller and session-timeouts. This is my setup

**localhost/somepage**      is showing an insert/update-Form, communicating via fetch() with
**localhost/sompage.json**  is inserting/updating and giving back the result
**somepage.php**            is the controller for somepage

It worked fine until I ran into session-timouts. I worked around those by putting this at the top of each page:

if($kirby->request()->is('POST') && !$kirby->user())
{
    $message = '{"status" : "loggedout", "message":"Idle for too long. Please log in again"}';
    echo json_encode($message);
    exit;
}

With that in place, whenever I did an ajax-request whith the session endet, the page returned this status-message so I could log in again and work on.

Then I added a controller somepage.php wich is giving me records from the database when I open localhost/somepage.

This works fine too, until the session ends and I try to do a fetch().
Then I don’t get the json-message any longer, instead I get an Error from the kirby-debugger saying
Call to a member function username() on null which ist pointing at my controller somepage.php where I have this: $user_name = $kirby->user()->username();.

Why is that? IS the controller executed before the page? I tried putting a redirect at the beginning of the return function in the controller

if($kirby->request()->is(‘POST’) && !$kirby->user()){ go(‘/login’); }
but it seems to be ignored.

Is there a better way of working with ajax and sessions?
Help is kindly appreciated :cry:

This is the sort of code that should never be used when dealing with class methods.

Always make sure you are dealing with an object of the class to which the method belongs:

$username = ( $user = $kirby->user() ) ? $user->username() : null;

ok, so if i get you right I shouldn’t do such a cascading thing with objects.

I changed my code to

$user = $kirby->user();
$user_id = $user->id();
$user_name = $user()->username();

Now the error is pointing at $user_id = $user->id()
And I still don’t understand, why this

if($kirby->request()->is('POST') && !$kirby->user())
{
    $message = '{"status" : "loggedout", "message":"Idle for too long. Please log in again"}';
    echo json_encode($message);
    exit;
}

in somepage.php is not executed when I reload the page and instead I get this error?

That doesn’t help, it’s basically the same code as you had before. Please do as advised above (or use an if statement if you don’t like the ternary operator).

The point here is not storing the user in a variable but to check that this variable actually is a user object.

If $kirby->user() returns null, $user will be null and you will get the same error message when calling id() or username() as before.

This code is only executed when a post request is sent and you are not logged in.

ok, thank you for your advices. Writing the code as pixelijn suggested, helps catching this specific error.

And since I didn’t explain the problem good enough, you couldn’t help me with what bugged me about the whole thing.

Here is the complete code I have in my header-snippet to avoid unauthorized access:

if($kirby->request()->is('POST') && !$kirby->user())
{
  $message = '{"status" : "loggedout", "message":"blablabla"}';
  echo json_encode($message);
  exit;
}
if (!$kirby->user()) 
{ 
	go('login'); 
}
else{ ...

So logging in, opening the somepage and fetching data via ajax works fine.
When the session times out another ajax-call brings me the above message.

And now I reloaded the page, expecting the code above redirects me to login-page. Then I received the errors from the controller.
But texnixes hint reminded me, that I was doing a post-request right before the reload.

So it seems, the browser is sending a post-request on reload without being logged in.
That explains, why the user-id is not available in the controller. But it doesn’t explain, why I don’t get the loggedout-status-message and why the request is passed through to the controller.

Are the controllers loaded before the pages?

The controller is loaded before the template, because its purpose is to pass the variables you return from there to the template.

I must admit that I’m somehow missing the whole picture, so that makes it hard to follow what you are doing where and why…

Why do you check for a post request in the header?

Why do you check for a post request in the header?

I added this

if($kirby->request()->is('POST') && !$kirby->user())
{

to make sure ajax-requests are intercepted when the session is timed out so that the script on the open page receives an understandable message.

I’m sure there is a better way to ensure authorization with ajax requests, but this worked for me …