Laravel Set up User Language - php

I have many controllers and I want to set this code in the all of this(actually all of project), how can i do that?
if( !empty(Input::get('lan')) ){
Auth::user()->language = Input::get('lan');
App::setLocale( Auth::user()->language );
}else{
App::setLocale( Auth::user()->language );
}

You can use Laravel's middleware for that. Middleware is a layer of code that wraps the request processing and can execute additional code before or/and after request is processed.
First, you need your middleware class. It needs to have one method called handle() that will do the desired logic. In your case it could look like that:
<?php namespace App\Http\Middleware;
use Auth;
use App;
class SetLang {
public function handle($request, Closure $next) {
if(empty($request->has('lan'))) {
if (Auth::user()) {
Auth::user()->language = $request->input('lan');
Auth::user()->save(); // this will do database UPDATE only when language was changed
}
App::setLocale($request->input('lan'));
} else if (Auth::user()) {
App::setLocale(Auth::user()->language);
}
return $next($request);
}
}
Then register the middleware in your App\Http\Kernel class so that it gets executed for every request:
protected $middleware = [
//here go the other middleware classes
'App\Http\Middleware\SetLang',
];
You can find more info about Middleware in the docs here: http://laravel.com/docs/master/middleware

Seems that with newest versions of Laravel (im on 5.8) for this middleware to work you need to place it under $middlewareGroups otherwise the call to Auth::user() its always empty.
Following jedrzej-kurylo answer, just move the middleware to:
protected $middlewareGroups = [
'web' => [
...
'App\Http\Middleware\SetLang',
],
];

Related

how to redirect properly using a global middleware in Laravel?

I created a custom middleware to redirect short urls to other urls, I have a Url model that has this information:
{
"id":1,
"original_url":"http://www.google.com",
"short_url":"http://127.0.0.1:8000/wGjxw",
"updated_at":"2023-02-08T21:05:39.000000Z",
"created_at":"2023-02-08T21:05:39.000000Z"
}
so I have created a middleware:
<?php
namespace App\Http\Middleware;
use App\Models\Url;
use Closure;
use Illuminate\Http\Request;
class RedirectMiddleware
{
public function handle(Request $request, Closure $next)
{
//dd('here'); // is not reaching this code
$url = Url::where('short_url', $request->fullUrl())->first();
if ($url) {
return response()->redirectTo($url->original_url);
}
return $next($request);
}
}
app/Http/Kernel.php
....
....
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\RedirectMiddleware::class,
...
...
But, when I hit the url http://127.0.0.1:8000/wGjxw I get a 404 error,
This is the web.php
Route::get('/', function () {
return view('main');
});
Route::post('/urls', [UrlsController::class, 'store'] );
These routes are for showing the page with the form, and for creating the short url and those are working properly, the problem is that it looks like the middleware is not registered or I don't know what is happening, what I want is the short_url gets redirected to the original_url, what can I do? thanks
If the middleware approach isn't working, you could make a route specifically for it using route model binding with short_url as the key.
https://laravel.com/docs/9.x/routing#customizing-the-key
Route::get('/{url:short_url}', fn (Url $url) => redirect()->away($url->original_url));
My error was that the middleware was in the $middlewareGroups property, and it should be in the $middleware property, now it is working properly

newrelic for laravel to track routes response time

I am trying to add newrelic to my laravel site. I found this repo. But couldn't use it properly.
Where should I put this code?
App::after( function() {
Newrelic::setAppName( 'MyApp' );
} );
Or maybe other ways to add routes response time to newrelic...
App::after does not exists anymore.
You can register a middleware that is executed after the request to do what you need:
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
Newrelic::setAppName( 'MyApp' );
return $response;
}
}
and register it as usually in app/Http/Kernel.php:
protected $middleware = [
...,
\App\Http\Middleware\AfterMiddleware::class
];

PHP Laravel protected route for subpage without authentication

I'm building a Laravel-app and I have a route where I need to include a third-party script/iframe. I want to protect that route with a simple access code without setting up the laravel-authentication.
Is that possible? If so, how can I achieve that?
All solutions I give below suggest you are trying to access your route with code=X URI/GET parameter.
Simple Route
You can simply check for the given code to be correct in each route's method, and redirect somewhere if that's not the case.
web.php
Route::get('yourRouteUri', 'YourController#yourAction');
YourController.php
use Request;
class YourController extends Controller {
public function yourAction(Request $request) {
if ($request->code != '1234') {
return route('route-to-redirect-to')->redirect();
}
return view('your.view');
}
}
Route with middleware
Or you can use middlewares for avoiding to repeat the condition-block in each route if you have many of them concerned by your checking.
app/Http/Middleware/CheckAccessCode.php
namespace App\Http\Middleware;
use Request;
use Closure;
class CheckAccessCode
{
public function handle(Request $request, Closure $next)
{
if ($request->code != '1234') {
return route('route-to-redirect-to')->redirect();
}
return $next($request);
}
}
app/Http/Kernel.php
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
// Other middlewares...
'withAccessCode' => \App\Http\Middleware\CheckAccessCode::class,
];
web.php
Route::get('yourRouteUri', 'YourController#yourAction')->middleware('withAccessCode');
You can create your own middleware.
Register the middleware in the $routesMiddleware of your app/Http/Kernel.php file.
Then use it like this:
Route::get('script/iframe', 'YourController#index')->middleware('your_middleware');
-- EDIT
You can access the route like this:
yoururl.com/script/iframe?code=200
Then in the middleware handle method:
if ($request->code !== 200) {
// you don't have access redirect to somewhere else
}
// you have access, so serve the requested page.
return $next($request);

Laravel Parameter in every url

I have read almost everything in web and documentation but i can't find solution for my Problem.
I have a variable stored in Session , then I want to put this variable in every url generated by route('some-route') .
In Session I have sub = "mysubid"
When I generate Route route('my-route') I want to pass this sub parameter in query string: http://domain.dom/my-route-parameter?sub=mysubid
Can you help me to solve This problem? Any helpful answer will be appreciated;
You can use the Default Values feature.
First create a new middleware php artisan make:middleware SetSubIdFromSession. Then do the following:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubIdFromSession
{
public function handle($request, Closure $next)
{
URL::defaults(['sub' => \Session::get('sub')]);
return $next($request);
}
}
At the end register your new middleware in app/Http/Kernel.php by adding it to $routeMiddleware.
protected $routeMiddleware = [
// other Middlewares
'sessionDefaultValue' => App\Http\Middleware\SetSubIdFromSession::class,
];
Add {sub} and the middleware to your route definition:
Route::get('/{sub}/path', function () {
//
})
->name('my-route')
->middleware('sessionDefaultValue');
Since you want this on every web route you can also add the middleware to the web middleware group:
protected $middlewareGroups = [
'web' => [
// other Middlewares
'sessionDefaultValue',
],
'api' => [
//
]
];
Try this , You need to create middleware php artisan make:middleware SetSubSession
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubsSession
{
public function handle($request, Closure $next)
{
if(session('sub')){
$url = url()->full();
return redirect($url.'?sub='.session('sub'));
}
return $next($request);
}
}
in app/http/Kernel.php
protected $routeMiddleware = [
........
'setsubsession' => \App\Http\Middleware\SetSubsSession::class,
]
in route.php add
Route::group(['middleware' => 'setsubsession'], function(){
//and define all the route you want to add sub parameter
});
using this you don't need to change all your routes.This will automatic add "sub" in the route define in that middleware.

Roles with laravel 5, how to allow only admin access to some root

I follow this tutorial : https://www.youtube.com/watch?v=kmJYVhG6UzM Currently I can check in my blade if user is a admin or not like this:
{{ Auth::user()->roles->toArray()[0]['role'] }}
HI ADMIN
#endif
How can I make my route only available for admin user?
You need to create a middleware for your route.
Use: php artisan make:middleware AdminMiddleware.
You will find in your middleware folder a new file with this name.
Put your logic in your middleware, e.g.
public function handle($request, Closure $next)
{
if(Auth::check())
{
return $next($request);
}
else
{
return view('auth.login')->withErrors('You are not logged in');
}
}
Once you have done your logic in your middleware, you can either call it in the route or make the middleware apply to all routes.
If you want to add it to all routes, go to Kernel.php and add it to the $middleware array, e.g.
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\AdminMiddleware',
];
If you want to add it to specific routes only, add it to the $routeMiddleware variable and add the alias to the route. E.g.
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
'admin' => 'App\Http\Middleware\AdminMiddleware',
];
You can then add it to a route, as a filter, e.g.
Route::get('admin/profile', ['middleware' => 'admin', function()
{
}]);
For additional info visit the docs:
http://laravel.com/docs/master/middleware
EDIT
An improvement on this would be to use variadic functions which was introduced in PHP 5.6
http://php.net/manual/en/migration56.new-features.php
Instead of having to make a middleware for each permission set you can do the following
PermissionMiddleware
namespace App\Http\Middleware;
use Closure;
use \App\Models\Role;
class PermissionMiddleware
{
// Pass parameters to this middleware
public function handle($request, Closure $next, ...$permitted_roles)
{
//Get a users role
$role = new Role;
$role_name = $role->getUserRoleByName();
foreach($permitted_roles as $permitted_role) {
if($permitted_role == $role_name) {
return $next($request);
}
}
return redirect()->back()->withErrors('You do not have the required permission');
}
}
Notice the ...$permitted_roles
Route::get('admin/profile', ['middleware' => 'PermissionMiddleware:Admin,Marketing', function()
{
}]);
You can now specify as many roles as required for one middleware rather than creating multiple by using middleware parameters
Docs
https://laravel.com/docs/5.3/middleware#middleware-parameters
Let's assume you have a column in your users table with isAdmin name which has a default value of 0 (false)
You can give special access using middleware in laravel like you give access to logged in users using auth middleware in laravel.
Now you need to create a middleware using the command :
php artisan make:middleware AdminMiddleware
In your Kernel.php you need to add this line to protected $routeMiddleware
'admin' => \App\Http\Middleware\AdminMiddleware::class,
In your middleware folder you have the AdminMiddleware file.
In that you need to put your logic
In this case this is how it might look like depending upon you
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->isAdmin == '1') // is an admin
{
return $next($request); // pass the admin
}
return redirect('/'); // not admin. redirect whereever you like
}
}
Now in your route you have to pass the url using this middleware
Here is how it might look like
Route::get('/iamanadmin', ['middleware' => 'admin', function() {
return view('iamanadmin');
}]);
use middleware and check for admin user.
Route::get('admin', ['middleware' => 'checkadmin', function()
{
}]);
now create middleware and validate admin user.

Categories