Change localization after redirecting - php

I wanna set localization in middleware, like if user is not authed redirect to login,
redirect works but next language is not changing like if current lang set as fr after redirecting it changes as en
here is code what I've tried App:setLocale() not effected
/Authenticate.php
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
App::setLocale('fr'); // I want to implement something like that, for all auth urls
return route('login','fr');
}
}
Can someone help, how to change login,register ... language with current lang.

Route returns and redirect to it does not occur
return redirect()->guest(route('login','fr'));

Related

Laravel verify locale in url is same as user's locale from database

So in my LocaleMiddleware class (which is located in the web group of the middleware), I have the following:
if (Auth::check())
{
app()->setLocale($request->user()->getLocale()); // This just fetches the locale from the database for the given user
}
And then it just returns the next request. However, there is a slight issue for example when logging in. I need to use the return redirect()->intended(); option. This poses a problem when I have for example the following route that I point to:
https://www.example.com/es/cervezas/dos
The English variant of this url would be:
https://www.example.com/en/beers/two
My routes look like this for example:
Route::name('user.')->prefix(app()->getLocale())->group(function () {
Route::get(trans('routes.beers'), [BeersController::class, 'index'])->name('beers.index');
}
So in my routes I translate everything, and I also have slugs for each of my database models etc, which is why I always need to have the correct locale set but also I always need to have the correct locale in the url. If not I get not found exceptions when viewing specific model items or weird translations.
But one of the main problems is, when I go to the Spanish route for example (or any route for that matter in any language), after logging in, it will return the intended url/route, which will be the English one since en is the fallback locale.
So basically, what I was thinking is something along the lines of this, in my LocaleMiddleware class:
if (Auth::check())
{
app()->setLocale($request->user()->getLocale());
// Check if the segment locale is the same as the user locale
// IF NOT, redirect them
if(request()->segment(1) !== $request->user()->getLang())
{
return redirect()->route(request()->route()->getName()); // Not sure what to do here, doing this just creates an endless loop because the locale somehow was not updated yet it seems
}
}
Any ideas for a solution for this, in the LocaleMiddleware or anywhere else? Or am I going about this the wrong way entirely? Any pointers are appreciated!
Edit:
Now in my LoginController I have the following:
protected function authenticated(Request $request, $user)
{
app()->setlocale($user->getLocale());
dd(app()->getLocale()); // This is the correct locale, `es` or `nl`
dd(route('beers.index')); // This just always shows the English route
}
How come the app()->getLocale() shows the correct locale but the route is still always in the default locale? And of course, how to fix that?
Usually you have access to the user in the login function before redirecting.
In many of my projects there is an admin panel and I use the same default login endpoint. During the login process I check where the user is an admin or not and decide where to redirect him.
Here's an example of the store function in App\Http\Controllers\Auth\LoginController in a laravel 8 project:
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
if (Auth::user()->hasRole('admin')) {
return redirect()->intended(RouteServiceProvider::ADMIN_HOME);
}
return redirect()->intended(RouteServiceProvider::HOME);
}
So I believe that if you edit your redirection logic in the login controller it should work, because you have access the user, before you actually redirect him.

Laravel intended always returns email/verify

I'm using Laravel 7.4, and I want to redirect the users to the page they came from after the login. I edited the file RedirectIfAuthenticated and added the redirect like:
return redirect()->intended(RouteServiceProvider::HOME);
But the problem is, it always redirected me to home. When I actually logged what the intended function returns, it always returns the url as website.com/email/verify. I'm 100% sure I don't redirect the users to that url, because I am logging in with an already verified user.
It might be some FW setup that I failed to notice, since I took over this project from another developer. I'll provide any more info if needed.
Check for middleware maybe you are redirecting unverified users to email/verify
Then in your LoginController create a protected function redirectTo() and return url()->previous();
Your code will look like this
protected function redirectTo()
{
return url()->previous();
}
Or
Also you can add $this->redirectTo = url()->previous() to your constructor
like this
public function __construct()
{
$this->redirectTo = url()->previous();
$this->middleware('guest')->except('logout');
}
Hope this helps
If you dump dd(session()->all()) of a so-called "intended" page, you will see the following:
As you can see, Laravel store user's previously intended page at url['intended'] array element. So to imitate this behavior manually, you have to set this value manually where needed. In this case it's LoginController:
public function showLoginForm()
{
session()->put('url.intended', url()->previous());
return view('admin.auth.login');
}
Now the original location has been stored, and later when the user log in, they will be redirected as declared in RedirectIfAuthenticated#handle:
return redirect()->intended(RouteServiceProvider::HOME);
But what if the user went to the /login page intentionally, or simply put, what if they refresh the page? url.intended will have the value of route('login'), then when user logged in, they will be redirected to login page and the infinite loop continues.
In that case, url.intended should not have any value. RouteServiceProvider::HOME value will be used as destination. There must be additional condition for that, let's say your site have login route named login:
public function showLoginForm()
{
if (($url()->previous() != route('login')) {
session()->put('url.intended', url()->previous());
}
return view('admin.auth.login');
}
Case anything unclear, you may want to have a look at similar question

Laravel redirect to home page

I am using Language switch to switch between English and Arabic. It is working fine in all the links except Home page.
If I have not authenticated it is working fine it is redirecting to http://domain.name/en/login
If I have authenticated or logged in and try to access the url http://domain.name/ it is redirecting to http://domain.name/home instead of a http://domain.name/en/home
I have changed in all the Auth files by adding a function:
public function redirectTo(){
return app()->getLocale().'/home';
}
The solution for this is to make a automatic redirect to the page.
Route::get('/home', function () {
return redirect(app()->getLocale());
});

Redirect user to specific section/div of page after login/registration

Suppose a user is looking into some section of page and he is not logged in. He than logs in through the link given in the page. How can I redirect the user to specific section that he was reading.
Note: I have already redirected the user to initial page but still can't redirect to the specific section.
Use the intended() method:
return redirect()->intended();
This method reads the url.intended value from the session and if it exists, the method redirects a user to this URL. If not, by default it redirects a user to /
To make it work with a section, use JS to get full URL:
window.location.href
Then you could make an AJAX call to save current URL to the session manually with:
session(['url.intended' => url()->full()])
Or you could put it into a hidden input and then in a LoginController get it from a request and save it to the session.
The way i did it:
In App\Http\Middleware\Authenticate.php i update the handle function like this:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect('login')->with(['lastUrl' => $request->url()]);
}
}
return $next($request);
}
The important part is return redirect('login')->with(['lastUrl' => $request->url()]);. That way i got the intended url the user tried to access before login so when i login i just redirect the user to the url he tried to access.
In case the user didn't try to access any page he is just redirected to the default welcome page.

Laravel Controller Routes

I'm using a controlled route as such
Route::controller('company', 'CompanyController');
In this Controller i have a getLogin and postLogin function, the getLogin shows the login view. To get there i need to go to company/login
Now i'm wondering how can i redirect company/ to company/login
I have the following working but is it good practice?
Route::get('company', 'CompanyController#getLogin');
Route::controller('company', 'CompanyController');
Thank you!
In this case, index methods will respond to the root URI, so what you can do is create a getIndex() function which will return Redirect::to('company/login'). You can probably do a check on this for a logged in user first as well, for example...
public function getIndex()
{
if(!Auth::check())
return Redirect::to('company/login');
// Continue with what should happen if the user is logged in.
}
This way, when someone goes to /company, it will redirect them to login if they aren't logged in already or it will continue doing whatever you want it to do or redirect them to the same page you are redirecting people to after they login.
This also means you can do away with that Route::get() that you have setup for company.

Categories