Implement session full support on administration pages
Currently the session is not fully working on the administration of WordPress.
The session driver is well loaded but no data can be stored or "fetched" from an administration page. If a session value defined on the front-end is still available to the session, it can still be returned from an administration page.
The main issue is that the session driver does not seem to store session data from the administration only.
I'm not sure if this is the same as the issue I'm having.
For some reason I am unable to get a session to persist across requests? I have middleware that sets "locale" But when I try to retrieve this value in controller....I get a blank value.
<?php
namespace App\Http\Middleware;
use Closure;
class CheckUserLocale
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->has('locale')){
$locale = $request->input('locale', env('USER_REGION'));
session(['locale' => $locale]);
}
return $next($request);
}
}
Controller::
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App;
class LocalizationController extends Controller
{
public function what_is_user_locale(){
$value = session('locale');
dd($value); // null
}
}
Thanks in advance.
@maximusblade Hmm not sure regarding your issue but I think it seems an issue with the order of the middleware stack. If your middleware is called before the session manager has been initialized (middleware), it is expected. You might want to try to sort your middlewares inside the App\Http\Kernel.php class:
- https://laravel.com/docs/5.8/middleware#sorting-middleware
The issue here is regarding the WordPress administration screens only.
@jlambe Hey thanks for the reply I have tried middleware sorting. I made sure that sessionStart fires off before any of my middleware. I'll open up a new issue since this may not be related.
@jlambe I've added a really nasty hack to get sessions working on admin pages. I think the problem is in the fact that the script gets killed when the admin page is loaded. In wp-admin/admin.php on line 292:
include( ABSPATH . 'wp-admin/admin-footer.php' );
exit();
I know, at least in Laravel, sessions do not persist when the script is killed with either exit or dd.
When i change the code to this:
include( ABSPATH . 'wp-admin/admin-footer.php' );
register_shutdown_function(function(){
app()['session']->save();
});
exit();
All sessions are saved.
The only thing is, i dont know how to properly implement this, but for now i can do my thing. Maybe this helps you come up with a good solution!
@pvdptje this is at least a very useful information to explore and for now the best thing to track, thanks!
I've found a cleaner solution, which doesn't require editing Wordpress core files. Make a new hook:
namespace App\Hooks;
use Themosis\Hook\Hookable;
use Themosis\Support\Facades\Action;
class PersistSessions extends Hookable
{
public function register()
{
Action::add('shutdown', function(){
app()['session']->save();
});
}
}
Register this in config/app.php and it works as well!
@pvdptje Sweet! I'll definitely test this trick.
@pvdptje This solution works. Though, I have been facing similar issues with wp_cache_* functions.
@pvdptje I've tested this and it does work better. One thing I haven't yet eluded is when using the session()->flash() method.
For unknown reasons, the session data is not persisted on the next request when using the flash method. Did you have the same issue in your tests ?
I just tested flash() and it didn't work. I don't really have time to dig into this, but i took a quick look and added some hacks to the session core files, and got it to work.
In illuminate\session\Middleware\Startsession on line 65 the save method is called on the driver. Comment this line out.
Make sure you use the file session handler, and in Illuminate\Session\FileSessionHandler
Change the write method to this:
static $written = false;
/**
* {@inheritdoc}
*/
public function write($sessionId, $data)
{
if(!static::$written){
$this->files->put($this->path.'/'.$sessionId, $data, true);
static::$written = true;
}
return true;
}
I've added the following code to a controller:
{
if(!session()->has('test')){
echo 'No flash data yet, setting it';
session()->flash('test', '123');
} else {
print_r(session()->all());
}
return view('test');
}
Sets the flash data the first request, and displays it the second. The write method on the handler is called multiple times, and the last time it just clears all flash data. No idea why (yet).