Laravel 4 Routes - laravel

How can I create admin specific routes in Laravel 4
(Restfull Controllers):
admin/users/ => UsersController#admin_index
admin/users/create => UsersController#admin_create
admin/pages/create => PagesController#admin_create
and how can catch any parameters in URL without add it in route file like $_GET

This is how you group route with a prefix
Route::group(array('prefix' => 'admin'), function()
{
Route::get('user','UsersController#admin_index');
Route::get('user/create','UsersController#admin_create');
Route::get('pages/create','PagesController#admin_create');
});
and to get parameters in route
Route::get('someName/{id}',Contoller#Func);
The Function has to be written like this
public function Func($id){
/**
*do the thing here
* $id is the parameter passed through url, you dont have to use $_GET['id']
**/
}

Related

Laravel localization and routes from Jetstream / Fortify

I have this new Laravel project to work on. We would like to make it available in multiple languages.
I started the project with JetStream. Routes for authentication and such are automatically handled by JetStream / Fortify. I then added https://github.com/mcamara/laravel-localization to handle the localization. it works fine for the routes I created myself :
Route::group(
[
'prefix' => LaravelLocalization::setLocale(),
'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ]
], function()
{
Route::get('/', function () {
return view('welcome');
});
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
But how can I set the group, prefix and middleware on the routes handled by Jetstream and Fortify?
[EDIT]
So after some suggestions from #TEFO, I'm trying to add a middleware to handle setting the locale. Added :
Fortify.php :
'path' => '{lang}',
'middleware' => ['web', 'setLang']
new middleware setLang :
class SetLang {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(\Illuminate\Http\Request $request, Closure $next) {
// $lang = 'en';
// $request->attributes->add(['lang' => 'en']);
$request->route()->setParameter('lang', 'en');
// $request->request->set('lang', 'en');
return $next($request);
}
}
Added the middleware to $routeMiddleware.
I'm receiving this error when trying to reach http://mylaravel/en/login :
ErrorException
Missing required parameters for [Route: login] [URI: {lang}/login]. (View: /var/www/resources/views/auth/login.blade.php)
Finally successfully nailed this. I simply disabled routes from Fortify and Jetstream, copied them over and shoved them inside my grouped prefix routes. Still using https://github.com/mcamara/laravel-localization but it should work anyway you want it - make your own system or whatever, as long as you control the routes you're good to go.
In JetstreamServiceProvider :
public function register() {
Jetstream::ignoreRoutes();
}
In FortifyServiceProvider :
public function register() {
Fortify::ignoreRoutes();
}
And copy over routes from Fortify vendor/laravel/fortify/routes/routes.php and Jetstream vendor/laravel/jetstream/routes/livewire.php (I guess adapt to Inertia if you're working with this) over to your web.php file, inside a route group with the prefix you need.
I faced almost the same problem with the expection that i do not use mcamara/laravel-localization at the moment.
Based on the useful discussion above between #JeremyBelolo and #TEFO, the following solution worked for me:
Added 'path' => '{locale}/my-secret-path' to config/fortify.php. As #JeremyBelolo and #ETO discussed, the support for that was recenlty added.
Added my middleware before \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class to the web $middlewareGroups
Where my middleware set the locale app()->setLocale($locale); and the default {locale} url parameter URL::defaults(['locale' => $locale]); before passing the request deeper into the application.
Considering Jetstream I had to apply the same steps as #JeremyBelolo did, exept I didn't copy the jetsream/livewire routes but used the following inside the route group:
require base_path('vendor/laravel/jetstream/routes/livewire.php');
Now I can access {locale}/my-secret-path/login where {locale} is a supported locale for my site.
UPDATE [Fortify config option changed]:
The path fortify config option changed to prefix. Thus in config/fortify.php the following key should be used:
'prefix' => '{locale}/my-secret-path'
I made a new Laravel Project using Jetstream. I wanted to use multi-language support in my project, but when I used Prefix (en/login, de/login) according to languages in url, I was also having a problem with Route. I solved my problem by following these steps. I hope you will be useful too:
1 - I have included the package on this https://github.com/mcamara/laravel-localization in my project. and followed the instructions sequentially.
2 - I made the Route settings in the "rautes\web.php" file as follows.
Route::group(['prefix' => LaravelLocalization::setLocale(),'middleware' => [
'localeSessionRedirect', 'localizationRedirect','localeViewPath' ]], function(){
/** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/
Route::get('/', function () {return view('welcome');});
Route::middleware(['auth', 'verified'])->get('/dashboard', function () {
return view('back.dashboard');})->name('dashboard');
});
3 - I have included the in app\Http\Middleware\Kernel.php. In middlewareGroups end of web prefix.
protected $middlewareGroups = [
'web' => [....
\Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
\Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
\Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
\Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
\Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class,]
4 - Fortify Routes, include prefix in vendor\laravel\fortify\routes.php - Route::group like this:
Route::group(['prefix' => LaravelLocalization::setLocale(),
'middleware' => config('fortify.middleware', ['web'])], function () {
$enableViews = config('fortify.views', true);
.......
5 - Livewire Routes, include prefix in vendor\laravel\jetstream\routes\livewire.php - Route::group like this:
Route::group(['prefix' => LaravelLocalization::setLocale(),
'middleware' =>config('jetstream.middleware', ['web'])], function () {
if (Jetstream::hasTermsAndPrivacyPolicyFeature()) {
Route::get('/terms-of-service', [TermsOfServiceController::class, 'show'])-
>name('terms.show');
Route::get('/privacy-policy', [PrivacyPolicyController::class, 'show'])-
>name('policy.show');}
6 - If you want to separate backend and frontend, you can add in app\Http\Middleware\Kernel.php end of protected $routeMiddleware with prefix like in this https://github.com/mcamara/laravel-localization.
protected $routeMiddleware = [
........
'localize'=> \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class,
]
7 - And the happy end...

Localization in laravel

I designed a site with Laravel. now I want add new language to it.I read laravel document . It was good but I have a problem.suppose I have a page that show detail of products so I have a route like mysite.com/product/id that get product's id and show it.also I have a method in controller like
public function showProduct($id){
...
}
If I add new Language , the route will change to this: mysite/en/product/id
now I must change my method because now two parameter send my method.something like this :
public function showProduct($lang,$id){
...
}
So two problems arise:
I must change all method in my site which is time consuming
I do not need language parameter in methods because I set $locan via middleware
pay attention that I do not want remove for example en from my URL (because of SEO)
Open your RouteServiceProvider and say that language parameter actually is not a parameter, it's a global prefix.
protected function mapWebRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => Request::segment(1) // but also you need a middleware about that for making controls..
], function ($router) {
require base_path('routes/web.php');
});
}
here is sample language middleware, but it's need to be improve
public function handle($request, Closure $next)
{
$langSegment = $request->segment(1);
// no need for admin side right ?
if ($langSegment === "admin")
return $next($request);
// if it's home page, get language but if it's not supported, then fallback locale gonna run
if (is_null($langSegment)) {
app()->setLocale($request->getPreferredLanguage((config("app.locales"))));
return $next($request);
}
// if first segment is language parameter then go on
if (strlen($langSegment) == 2)
return $next($request);
else
// if it's not, then you may want to add locale language parameter or you may want to abort 404
return redirect(url(config("app.locale") . "/" . implode($request->segments())));
}
So in your controller, or in your routes. you don't have deal with language parameter
Something like
Route::group(['prefix' => 'en'], function () {
App::setLocale('en');
//Same routes pointing to the same methods...
});
Or
Route::group(['prefix' => 'en', 'middleware' => 'yourMiddleware'], function () {
//Same routes pointing to the same methods...
});

How to use multiple method in single route in laravel

I want to use more than one method in a single route using laravel. I'm try this way but when i dd() it's show the plan string.
Route::get('/user',[
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
When i dd() 'roles' option it's show the plan string like this.
"roles" => "HomeController#useroles"
my middleware check the role this way.
$actions=$request->route()->getAction();
$roles=isset($actions['roles'])? $actions['roles'] : null;
The simplest way to accept multiple HTTP methods in a single route is to use the match method, like so:
Route::match(['get', 'post'], '/user', [
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
As for your middleware, to check the HTTP request type, a tidier way would be:
$method = request()->method();
And if you need to check for a specific method:
if (request()->isMethod('post')) {
// do stuff for post methods
}
Here's how you can do multiple methods on a single route:
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
/* Would be easier to use
* Route::put('/route/{route}', 'RouteController#update');
* Since Laravel gives you the Model of the primary key you've passed
* in to the route.
*/
Route::delete('/route', 'RouteController#destroy');
If you've written your own middleware, you can wrap the routes in a Route::group and apply your middleware to those routes, or individual routes respectively.
Route::middleware(['myMiddleware'])->group(function () {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Or
Route::group(['middleware' => 'myMiddleware'], function() {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Whichever is easier for you to read.
https://laravel.com/docs/5.6/routing#route-groups

How to add dynamically prefix to routes?

In session i set default language code for example de. And now i want that in link i have something like this: www.something.com/de/something.
Problem is that i cant access session in routes. Any suggestion how can i do this?
$langs = Languages::getLangCode();
if (in_array($lang, $langs)) {
Session::put('locale', $lang);
return redirect::back();
}
return;
Route::get('blog/articles', 'StandardUser\UserBlogController#AllArticles');
So i need to pass to route as prefix this locale session.
If you want to generate a link to your routes with the code of the current language, then you need to create routes group with a dynamic prefix like this:
Example in Laravel 5.7:
Route::prefix(app()->getLocale())->group(function () {
Route::get('/', function () {
return route('index');
})->name('index');
Route::get('/post/{id}', function ($id) {
return route('post', ['id' => $id]);
})->name('post');
});
When you use named routes, URLs to route with current language code will be automatically generated.
Example links:
http://website.com/en/
http://website.com/en/post/16
Note: Instead of laravel app()->getLocale() method you can use your own Languages::getLangCode() method.
If you have more questions about this topic then let me know about it.
Maybe
Route::group([
'prefix' => Languages::getLangCode()
], function () {
Route::get('/', ['as' => 'main', 'uses' => 'IndexController#index']);
});

How to call function in __constructor using laravel 5?

I am fetching menus from database based on user rights and displaying it to my web page but if i access any url whose access i don't have then too it opens that page.
For this i have created and called access_denied function which redirect user's home page.
I have called access_denied function from constructor of AuthController because AuthController gets loaded on each page.
I have used following code
AuthController
public function __construct()
{
$this->accessDenied();
}
public function accessDenied()
{
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
}
But I am getting following error
Non-static method Illuminate\Http\Request::segment() should not be called statically, assuming $this from incompatible context
If i using incorrect process then please suggest me correct way to redirect unauthorised user on home page.
First, you should create a middleware. In a command prompt type:
php artisan make:middleware AccessDenyMiddleware
Then you go to app/Http/Middleware/AccessDenyMiddleware.php and fill in the handle function {your own code}
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
But add the following line
return $next($request); // If passed, proceed with the route
Then, in a route, you should type:
Route::get('/yoururlhere', ['middleware' => 'AccessDenyMiddleware', function() { /* Put your work here */ } ]);
There are much better approaches. Like Authorisation if you are using Laravel 5.2
Or maybe change the default Authenticate middleware if you are using Laravel 5
You can use a middleware for thath https://laravel.com/docs/5.2/middleware#introduction.
php artisan make:middleware RoleRouteMiddleware
You should put thath code in the handle method of the middleware "App\Http\Middleware\RoleRouteMiddleware" and use the $request variable instead of the facade Request.
The middleware would filter earch request to your app.
Register a middleware, add it on app/Http/Kernel.php at routeMiddleware array
protected $routeMiddleware = [
....
'alias' => App\Http\Middleware\RoleRouteMiddleware::class,
];
and then use it on specific routes like this:
Route::get('admin/profile', ['middleware' => 'alias', function () {
//your code here
}]);
or in route gruoups:
Route::group(['middleware' => 'alias', function () {
//your filtered routes
}]);

Resources