Laravel access session data inside web.php - php

I can't use localization prefix because of my client's needs. I'm trying to store locale data into session and group my routes based on that 'locale'. But i cant access session data inside web.php.
$locale = Session::get('locale');
if($locale == 'tr') {
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
} elseif ($locale == 'eng){
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
}
LanguageController middleware
class LanguageController extends Controller
{
public function index($locale = ''){
if ($locale == '') {
Session::put('locale', 'eng');
} else {
Session::put('locale', $locale);
}
return redirect()->back();
}
}

You don't need to conditionally set routes if there's no conflicts.
The following works just fine:
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
If you want to restrict non-localised routes from being accessed then you do need session access but you can have that via middleware e.g.:
class LocaleRestricted {
public function handle($request, $next, ...$localesAllowed) {
if (!in_array(Session::get('locale'), $localesAllowed)) {
abort(404, 'This route is not available for this locale');
}
return $next($request);
}
}
You then need to register this locale in your app/Http/Kernel.php:
// ...
protected $routeMiddleware = [
// ...
'locale_restricted' => LocaleRestricted::class
];
Then you can use it as:
$locale = Session::get('locale');
Route::middleware('locale_restricted:tr')->group(function () {
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
});
Route::middleware('locale_restricted:eng')->group(function () {
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
});

For Get Data from session you can use
$value = $request->session()->get('your-key-name');
But I'm not sure It works in Web.php or not..!! But you can use this one in Controller, Middelware etc many more places.
For More Details See Laravel Official Documentation

Related

Laravel route locale middleware not working with model binding

I use this guide: https://mydnic.be/post/how-to-build-an-efficient-and-seo-friendly-multilingual-architecture-in-laravel-v2
I have these routes and middleware:
$locale = request()->segment(1);
Route::middleware('localized')->prefix($locale)->group(function() {
Route::get('/contacts', 'ContactController#index');
Route::get('/page/{page}', 'PageController#index');
});
And middleware localized from Kernel.php -> routeMiddleware:
public function handle(Request $request, Closure $next)
{
if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
$segments = $request->segments();
$segments = Arr::prepend($segments, config('app.fallback_locale'));
if($request->session()->has('language')) {
$segments[0] = session('language');
}
return redirect()->to(implode('/', $segments));
}
return $next($request);
}
When I access to: site.test/contacts he redirect me on locale: site.com/en/contacts
When I access to site.test/page/test I got 404 not found, If I access to: site.com/en/page/test then page working. Problem with redirect on locale with route model binding.
In Controller Page I have:
public function index(Page $page)
{
return view('page', compact('page'));
}
In translatable.php:
'locales' => [
'de' => 'Deutsch',
'en' => 'English',
],
In AppServiceProvider:
public function boot()
{
if(array_key_exists(request()->segment(1), config('translatable.locales'))) {
app()->setLocale(request()->segment(1));
}
}
I was able to work around this but this cost us access to the session, which you checked for to know if the session has "language" if yes, then prepend locale value should be set to the language value in the session. Below is what I did;
In Routes File
$locale = request()->segment(1);
Route::prefix($locale)->group(function() {
Route::get('/contacts', function(){
echo "hello contact";
});
Route::get('/page/{page}', function(Request $request, $page){
return "hello Page {$page}";
});
});
In MiddleWare File I did
public function handle(Request $request, Closure $next)
{
if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
$segments = $request->segments();
$segments = Arr::prepend($segments, config('app.fallback_locale'));
// Remove the session check as we don't have access to session yet
/*if($request->session()->has('language')) {
$segments[0] = session('language');
}*/
return redirect()->to(implode('/', $segments));
}
return $next($request);
}
Now in Kennel.php File for Middleware, Add your middleware class in the $middleware array
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
...
\App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];
Then try access site.test/page/1000 ... it will be redirected to site.test/{app.fallback_locale}/page/1000. In my case site.test/en/page/1000
UPDATE
After reading through this issue on git for laravel, I then thought of adding the session before the Localized middle class and it worked. I'm not sure if this is good practice but it got the job done.
In MiddleWare File I did
public function handle(Request $request, Closure $next)
{
if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
$segments = $request->segments();
$segments = Arr::prepend($segments, config('app.fallback_locale'));
// We can have session back on
if($request->session()->has('language')) {
$segments[0] = session('language');
}
return redirect()->to(implode('/', $segments));
}
return $next($request);
}
Now in Kennel.php File for Middleware, Add Session middleware before Localized Middleware class
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
...
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

Laravel improve Code for checking Userstatus

In my application I can mark a user as blocked. After a blocked mark he can't do anything.
My solution was to check the status in every construct controller and if the authenticated user is marked as blocked he will redirect to the view.
But my solution isn't very good because i have dublicated code and i have to check for the actual route.
Here is my code:
public function __construct()
{
$this->middleware('auth');
$this->middleware(function ($request, $next)
{
$this->user= Auth::user();
if(strcmp(Route::currentRouteName(), 'user.password.show') != 0)
{
if(strcmp(Route::currentRouteName(), 'user.password.set') != 0)
{
if(strcmp(Route::currentRouteName(), 'user.blocked.show') != 0)
{
if($this->user->status == Userstatus::where('type', 'passwordSetFalse')->first()->id)
{
Session::flash('error', 'Bitte setzen Sie ihr Passwort!');
return Redirect::route('user.password.show');
}
else
{
return $next($request);
}
}else
{
return $next($request);
}
}
else
{
return $next($request);
}
}
else
{
return $next($request);
}
});
}
I search a solution where i put the code once and i can use it for all my controller but i have no idea where the code can be written in.
Many thanks for your help
Take a look at Laravel Middlewares. Define a middleware that checks for the user status before passing the request to the controllers, than register your middleware in app/Http/Kernel.php.
<?php
namespace App\Http\Middlewares;
class UserBlockedMiddleware
{
public function handle($request, $next)
{
$user = \Auth::user();
if($user->status == 'blocked') abort(403);
return $next($request);
}
}
To learn more on how to register a global middleware check this section in Laravel docs.
You need to read about Protecting Routes
You can attach auth middleware to routes you want to protect, or directly in the __construct of your controller
Laravel ships with an auth middleware, which is defined at Illuminate\Auth\Middleware\Authenticate
If you want your own Auth middleware you can type the following
php artisan make:middleware MyOwnAuth
Also you can actually reduce the code like that
public function __construct()
{
$this->middleware('auth');
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
if (
strcmp(Route::currentRouteName(), 'user.password.show') != 0
&& strcmp(Route::currentRouteName(), 'user.password.set') != 0
&& strcmp(Route::currentRouteName(), 'user.blocked.show') != 0
&& $this->user->status == Userstatus::where('type', 'passwordSetFalse')->first()->id
) {
Session::flash('error', 'Bitte setzen Sie ihr Passwort!');
return Redirect::route('user.password.show');
};
return $next($request);
});
};

Laravel localization in 404 page using session

I set locale in middleware using session variable and it is working perfectly except 404 page. As I understood, neither session variables nor middleware works in exception handler. Here is my code:
Route:
Route::get('setlocale/{locale}', function ($locale) {
if (in_array($locale, \Config::get('app.locales'))) {
Session::put('locale', $locale);
}
return redirect()->back();
})->name('lang.switch');
Middleware:
class Language
{
public function handle($request, Closure $next)
{
$raw_locale = Session::get('locale');
if (in_array($raw_locale, Config::get('app.locales'))) {
$locale = $raw_locale;
} else $locale = Config::get('app.locale');
App::setLocale($locale);
return $next($request);
}
}
Any ideas?

laravel one route with multiple controllers based on user role

So i'm trying to achieve something, that seems is impossible. I want some routes in my application to use different controller based on user role. This is the approach i'm trying, but it doesn't work well. The user routes work, but admin routes return and Trying to get property on non object error in the VerifyCsrfToken.php file*
Route::group(array('middleware' => 'isAdmin'), function() {
Route::get('/', 'Admin\TestController#getIndex');
});
Route::group(array('middleware' => 'isUser'), function() {
Route::get('/', 'User\TestController#getIndex');
});
My middlewares
public function handle($request, Closure $next)
{
if(Auth::user()->isAdmin()) {
return $next($request);
}
}
public function handle($request, Closure $next)
{
if(Auth::user()->isUser()) {
return $next($request);
}
}
I've seen some handle this kind of situation, by just handling this in the controllers or even checking the use role inside the routes file, but I would rather use middlwares, so my routes file would be cleaner
You can do something like this:
Route::get('/', function () {
if (auth()->check()) {
if (auth()->user()->isAdmin()) {
return redirect()->route('');
} elseif (auth()->user()->isUser()) {
return redirect()->route();
} else {
return view('index');
}
}
return redirect()->to('login');
});
The error message has probably nothing to do with the code your show.
But using multiple controllers on one route is impossible, I asked the same question once.
But you could just use one controller and handle the authorization in that controller.
For example:
public function getIndex()
{
if(Auth::user()->isAdmin()) {
//Admin
return $this->getAdminIndex();
} else {
//No admin
return $this->getUserIndex();
}
}
protected function getAdminIndex()
{
return view('admin.index');
}
protected function getUserIndex()
{
return view('user.index');
}
But the cleanest way to do it is to just have 2 routes.

Laravel 5.2 assigning same route to different controller action by conditions

I wish to route the same route to different controller base on user type.
Such as
if (Auth::check() && Auth::user()->is_admin) {
Route::get('/profile', 'AdminController#show');
} elseif (Auth::check() && Auth::user()->is_superadmin) {
Route::get('/profile', 'SuperAdminController#show');
}
But this doesn't work.
How can I make it works as what I want?
You can do this
Route::get('/profile', 'HomeController#profile'); // another route
Controller
public function profile() {
if (Auth::check() && Auth::user()->is_admin) {
$test = app('App\Http\Controllers\AdminController')->getshow();
}
elseif (Auth::check() && Auth::user()->is_superadmin) {
$test = app('App\Http\Controllers\SuperAdminController')->getshow();
// this must not return a view but it will return just the needed data , you can pass parameters like this `->getshow($param1,$param2)`
}
return View('profile')->with('data', $test);
}
But i think its better to use a trait
trait Show {
public function showadmin() {
.....
}
public function showuser() {
.....
}
}
Then
class HomeController extends Controller {
use Show;
}
Then you can do the same as the above but instead of
$test = app('App\Http\Controllers\AdminController')->getshow();// or the other one
use this
$this->showadmin();
$this->showuser(); // and use If statment ofc
okey you can do that by creating a route::group
your route group will be like that
route::group(['prefix'=>'yourPrefix','middleware'=>'yourMiddleware'],function(){
if (Auth::check() && Auth::user()->is_admin)
{
Route::get('profile', 'AdminController#show');
}
else
{
Route::get('profile', 'SuperAdminController#show');
}
});
I hope that will help you.

Categories