Laravel - change route in middleware - laravel

Let's say I have this kind of URLs :
example.com/en/
example.com/en/login
example.com/fr/login
I would like to use a middleware to set the language and then return the route to be handled without the language part. So the router would get / or /login, without any language stuff.
public function handle(Request $request, Closure $next) {
app()->setLocale($request->segment(1));
// $request->server->set('REQUEST_URI', substr($_SERVER['REQUEST_URI'], 4));// not working
return $next($request);
}

I would suggest to store the language in session and use a middleware to setLocale.
Working example
SetLocale.php middleware
public function handle($request, Closure $next)
{
if (Session::has('language'))
{
App::setLocale(strtolower(Session::get('language')));
}
return $next($request);
}
Controller function to set language to session
public function setLanguage(string $language)
{
if (Session::has('language'))
{
Session::forget('language');
}
Session::put('language', $language);
return redirect()->back();
}
So now on everything that happens on the website, the middleware will check the language and set it to what's in session.
Also don't forget to specify the middleware in $middlewareGroups in app\Http\Kernel.php
You can create a form anywhere on website for the user to choose his language preference with a route to the controller function.

Related

laravel Localization per user

How do I change the language of each user? For example, some people don't change the language. Some people change the language.
Middleware :
use Closure;
use Auth;
class Localization
{
public function handle($request, Closure $next)
{
if(\Session::has('locale')) {
\App::setLocale(\Session::get('locale'));
}
return $next($request);
}
}
Save the locale for each user in database. This way you can override app's default locale to user's preferred locale in the middleware.
public function handle($request, Closure $next)
{
if($user = Auth::user()) {
App::setLocale($user->locale);
}
return $next($request);
}
If the your application doesn't require user to be authenticated, you can save locale in session for each user when the user change language.
Your method is right, no need to change the middleware. You can put the session on user with controller, like this below way.
Route :
Route::get('/lang',[
'uses' => 'HomeController#lang',
'as' => 'lang.index'
]);
Controller :
public function lang(Request $request)
{
$user = Auth::user()->id;
$locale = $request->language;
App::setLocale($locale);
session()->put('locale', $locale);
// if you want to save the locale on your user table, you can do it here
return redirect()->back();
}
Note : I added the GET method on route, so your URI will be like http://127.0.0.1:8000/lang?language=en, and o controller $request->language will catch the language parameter from your Request. You can modify and use POST method instead

Laravel - Delete Cookie in Middleware

I have a middleware in my project that call in every request. It will check if Request has a specific cookie, then delete another cookie. But it seems Cookies are not forgotten or set in Laravel until return in the response. something like
return response('view')->withCookie($cookie); that is not possible in middlewares.
Also I tried Cookie::queue(Cookie::forget('myCookie')); nothing happened and cookie is shown in my browser.
This is my middleware handle method:
public function handle(Request $request, Closure $next)
{
if (! $request->cookie('clear_token')) {
cookie()->forget('access_token'); # not worked
Cookie::queue(Cookie::forget('access_token')); # not worked
}
return $next($request);
}
You can change the response in middleware too:
https://laravel.com/docs/5.0/middleware
<?php namespace App\Http\Middleware;
class AfterMiddleware implements Middleware {
public function handle(\Illuminate\Http\Request $request, \Closure $next)
{
$response = $next($request);
// Forget cookie
return $response;
}
}

How to use middleware on routes in laravel?

I need to implement a little functionality for my application.
I have a form for editing and only admin must have access to it.
I can't figure out how to arrange the routes correctly, because I get
"The site has redirected too many times."
middleware:
class AdminMiddleware
{
public function handle($request, Closure $next)
{
$user = new User();
if ($user->role_id !==1) {
return redirect('/');
}
return $next($request);
}
}
route:
Route::post('/product', 'IndexController#store');
Route::get('/product', 'IndexController#index');
Route::get('/product/create', 'IndexController#create');
Route::put('/product/{product}', 'IndexController#update');
Route::get('/product/{product}/edit', 'IndexController#edit')->middleware('admin');
This route should be available only for admin
'/product/{product}/edit'
What am I doing wrong?

Conditionally set a URL to redirect to after authentication

In my app, a post author can set an otherwise public post to private. If an unauthenticated user tries to visit that post, they will be prompted to login.
After they authenticate, I want to redirect them back to the original post URL, so they can read that private post.
This behavior is normally handled by Laravel's default auth middleware. However, because the posts are often public, I can't use that in this case.
Here's my current, non-functioning middleware:
public function handle($request, Closure $next)
{
$post = $request->route('post');
if ($post->isPrivate()) {
$request->session()->setPreviousUrl($request->url());
return redirect()->guest('login');
}
return $next($request);
}
My hope is that I can set a custom URL to redirect to (/posts/{id}). However, when I try to login, I'm redirected to my default $redirectTo property (/dashboard).
Is this something that's feasible? Am I even thinking about this in the correct way?
#adam, thanks for the assist!
For anyone else looking, here's my final code:
Middleware:
public function handle($request, Closure $next)
{
if (auth()->check()) {
return $next($request);
}
$post = $request->route('post');
if ($post->isPrivate()) {
$request->session()->setPreviousUrl($request->path());
return redirect()->guest('login');
}
return $next($request);
}
LoginController:
protected function authenticated(Request $request, $user)
{
if ($request->session()->has('url.intended')) {
return redirect($request->session()->get('url.intended'));
}
}

Is it possible and how do I if so to pass a variable parameter to a Middleware in Laravel

I looking to set up a Middleware to check if the user is a subscriber to the page that they are on. I have tried a couple of options but both has required passing the URL to the Middleware.
The Route
Route::get('premium/{id}', function ($id) {
return $id;
})->middleware('subscribe:{$id}');
The Middleware
public function handle($request, Closure $next, $subscribe)
{
//dd($subscribe);
$c = DB::table('suscribes')->where('user_id', $request->user()->id)->where('subscribed_to', $subscribe)->count();
return $next($request);
}
The above $subscribe obviously returns a string of {$id} but have tried concatenating. Is there a better way?
As I am using Cashier and Stripe I have also tried setting up a new plan for each user. From docs.
public function handle($request, Closure $next)
{
if ($request->user() && ! $request->user()->subscribed('main')) {
// This user is not a paying customer...
return redirect('billing');
}
return $next($request);
}
But I still need to pass the variable to 'main'.
I'm not sure if I understand your requirement completely. But to get the value of some Requests route Parameter you can use $request->route('param-identifyer') function. Passing {$id} as parameter to the middleware is the wrong approach.
public function handle($request, Closure $next, $subscribe)
{
dd($request->route('id'));
$c = DB::table('suscribes')->where('user_id', $request->user()->id)->where('subscribed_to', $subscribe)->count();
return $next($request);
}

Resources