How to write laravel 5.8 controllers routes similar to laravel 5.1 - laravel

Having more than 20 controllers. It's very difficult to set each and every routes for add, edit and delete (also having more actions).
This is my laravel 5.1 routes.php :
Route::controllers([
'user' => 'UserController',
'taxes' => 'TaxController',
]);
Is there any way to support these routes in laravel 5.8?

You can use the Resource Controller and implement in routes/web.php. It will autogenerate the name for the route
//web.php
Route::resource('user', 'UserController');
Route::resource('taxes', 'TaxController');
Edit 1
If you want to exclude show method of the controller for the resource, You can add array inside the except method.
Route::resource('taxes', 'TaxController', [
'except' => ['show']
]);
Further, if you want to get only selected options, You can use only.
Route::resource('taxes', 'TaxController', [
'only' => ['index', 'create', 'store', 'edit']
]);

The controllers method was deprecated in Laravel 5.2. From the upgrade guide:
Implicit controller routes using Route::controller have been deprecated. Please use explicit route registration in your routes file.
1) Use Resource Routes
Provided that your controllers use the standard index, store, show etc methods you can simply use resource routes. For example:
Route::resource('user', 'UserController');
However if you want to exclude certain methods you can add them to the resource. For example:
Route::resource('user', 'UserController', ['except' => 'show']);
2) Declare Routes Explicitly
You can follow the Laravel 5.2 upgrade guide as above and instead declare each route explicitly.
3) Create a Macro
The Laravel router is Macroable. This means that you can add your own methods to it. For example, in your app service provider you could have the following:
Illuminate\Routing\Router::macro('controllers', function ($routes) {
// Create your own implementation of the controllers method.
});
This allows you to create your own implementation of the controllers method which means you wouldn't need to alter your routes or controllers, but you may need to dive in and look at Laravel's route handling to understand how to implement this.
I hope this helps.

You can use in the array, In as you call using routes. like {{route('claimsubmit')}}
Route::resource('claimform',array('as'=>'claimform','uses'=>'UserController#claimform');

Related

Laravel 5.6 additional Route::resource() Parameters

I would like to know how to add additional parameters to Laravel's Route Resource without using Query Strings.
I created a controller (CustomerController) with all the built-in resources and then, added the following route:
Route::resource('customers', 'CustomerController');
What i would like to do is add additional parameters to some of the default resources without creating custom routes or using query strings. For example:
Default resource with optional parameter (index):
public function index($page = 0)
{
//...
}
Desired URL:
http://www.example.com/customers
http://www.example.com/customers/{page}
I tried the following, but i get a not found exception (NotFoundHttpException):
Route::resource('customers', 'CustomerController')->parameters([
'index' => 'page'
]);
Is this possible? If so, how can i accomplish it?
Resource Controllers must implement a defined set of methods which are then mapped to the appropriate HTTP verb and path by the router. These methods, paths and verbs form part of a contract that cannot be adjusted, otherwise working with a Laravel application that implements Resource Controllers would be a headache.
Resource Controllers excel in providing the same experience across all Laravel applications, if your application requires behaviour that isn't supported out of the box by Resource Controllers then it is a sign that you should not be using them and should instead register your routes manually.
If you have just one route that needs to implement custom behaviour then you can register some methods instead of all and then choose to register a custom route to your Resource Controllers method, something like:
Route::resource('customers', 'CustomerController')->except([
'index'
]);
Route::get('/customers/{page?}', 'CustomerController#index');
The documentation on Resource Controllers covers except and only.
Try this :
Route::resource('customers', 'CustomerController')->parameters([
'customers' => 'page'
]);
The example above generates the following URIs for the resource's show route:
/customers/{page}
you set the name route: 'index' replace it by the variable : 'customers' name of your ressource

Laravel using an OR style combination in Route Middleware

I am trying to use multiple middleware in a route as follows
Route::get('devices', ['as' => 'devices.index', 'uses' => 'deviceController#index', 'middleware' => ['permission:manage_devices', 'permission:device.view']]);
This will implement AND logic between the two middlewares. I want to implement an 'OR' Logic but could not find any help.
Tough it isn't the most eloquent solution, you could try to create your own middleware that loads other middleware in a if/else or switch statement. That way you might be able to achieve the behaviour you'd want.
Check the docs on the link below on how to program your own middleware:
https://laravel.com/docs/5.3/middleware#defining-middleware

How to declare routes with resources in Laravel 5.2

I have some routes in routes.php in laravel
// Code for rounting admin panel
Route::resource('/admin','Admin\LoginController#index');
Route::resource('/admin/dashboard','Admin\AdminController#index');
Route::resource('/admin/movies','Admin\MovieController#index');
Now when I access url http://localhost/askspidy/admin I want to show login page and it works, but when i access url http://localhost/askspidy/admin/dashboard it should go to dashboard but it's showing me login page only.
I know this is because when it found /admin in any url it's bydefault goes to the route
Route::resource('/admin','Admin\LoginController#index');
I know it's assuming that (/admin) is route to controller and (/dashboard) is the function declared in the controller but I want routing like this only so is there any other solution for this problem.
A RESTful Resource Controller takes over the responsibility of each action. You only need to list the name and the controller:
Route::resource('photo', 'PhotoController');
If you wanted to only use the index method, you’d list it like this:
Route::resource('photo', 'PhotoController', ['only' => [
'index'
]]);
However, it looks like two of your routes are not suitable for resources (login and dashboard), as they should relate to editing a model.
You should instead just use a get() resource instead.
From the docs:
Route::get('user/{id}', 'UserController#showProfile');
So in your case, it would be:
Route::get('/admin','Admin\LoginController#index');
Route::get('/admin/dashboard','Admin\AdminController#index');
Route::resource('/admin/movie','Admin\MovieController');

Undefined variable: errors in Laravel

When I want to register a user in my laravel project, the page always says
Undefined variable: errors (View: /var/www/resources/views/auth/register.blade.php)"
According to the Laravel documentation, $errors should always automatically be set:
So, it is important to note that an $errors variable will always be available in all of your views on every request, allowing you to conveniently assume the $errors variable is always defined and can be safely used.
I have this on on every view when I use:
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
or any other way when I want to use the $errors variable.
Why is this? I never had this problem before.
Can someone help me please?
You should make sure that in app/Http/Kernel.php in middlewareGroups property for web you have:
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
in this array. Compare this with https://github.com/laravel/laravel/blob/master/app/Http/Kernel.php
EDIT
It seems you need to add 'middleware' => 'web' for route you are using or put \Illuminate\View\Middleware\ShareErrorsFromSession::class, into $middleware property array
or
Inside of the routes.php file try to create your routes within the following block
Route::group(['middleware' => ['web']], function () {
//routes here
});
UPDATE FOR NEWER VERSIONS OF LARAVEL APPLICATION
Be aware that you might run into problems also in case you use web middleware twice. There was a change in Laravel application 5.2.27 (don't confuse it with Laravel framework you use at the moment - you might use Laravel framework for example 5.2.31 but have Laravel application in version 5.2.24) in which web middleware is applied automatically for all routes. So in case of problems, you should open your app/Providers/RouteServiceProvider.php file and verify its content.
You can compare it also here :
RouteServiceProvider for Laravel application 5.2.24
RouteServiceProvider for Laravel application 5.2.27
In case you have newer version (that applies web middleware automatically), you shouldn't use web middleware in routes.php anymore or you should modify your RouteServiceProvider method to not apply web group middleware. Otherwise if web middleware group is automatically applied in this provider and you use it also in routes.php you might get very unexpected results.
I had this very same issue with Laravel 5.2.x.
Inside of the routes.php file try yo create your routes within the
Route::group(['middleware' => ['web']], function () {
//routes here
}
statement.
Also to be aware of: If you write tests and your view has $errors variable make sure you don't use WithoutMiddleware trait.
I had similar problem and solved this one by adding routes into middleware property array as well,
BUT
it worked only after calling php artisan route:cache (clearing route cache) subsequently.
I hope some of you would find this useful.
I was seeing this error too and later realised I had used the WithoutMiddleware trait as a means to bypass authentication for this particular test, but it ended up removing the validation error binding too. So I had to stop using the trait to keep the views working.
Go to App\Http\Kernel.php file. Move all the things of $middlewareGroups properties to $middleware.
Check for more details-
http://www.tisuchi.com/laravel-5-2-undefined-variable-error-validation/
count is not really realiable since it assumes the variable already exists. change the condition check to: #if($errors->has()) or just #if($errors)
Also if you are redirecting make sure to use this in your controller
return redirect()->back()->with('errors', $validator->messages());
EDIT: seen now that you are using L5.2
This may answer your question - you need to put your Routes in Route group.
Laravel 5.2 validation errors
protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Social\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Social\Http\Middleware\VerifyCsrfToken::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
],
'api' => [
'throttle:60,1',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
make your kernel look like this
Your problem will be fixed by using this method.
Route::group(['middleware' => ['web']], function () {
//routes should go here
});
If this doesn't help you, just run the following artisan command in addition to the above code:
php artisan key:generate
I solved in this way while using 5.2.*

Laravel 5 - Assign Middleware to Controller Namespace

I need to do an ACL check for the user before allowing access to the admin panel of a Laravel 5 website. What is the best way to do this for an entire controller group in the namespace App\Http\Controllers\Admin\*? Ultimately, I'm looking for a "set and forget" method to do this, and middleware looks like the best option so far.
The initial idea was to assign a middleware to the admin route, but this does not prevent any other non-admin route from accessing the controllers. This means a route can still target the admin controllers and bypass the ACL check.
The next idea was to insert the assignment in the constructor on the controllers, but this would require each additional controller to explicitly include the middleware. This would require a developer to know that the middleware should be included, which allows them to miss it entirely. This also applies to using one base controller as the parent for all admin controllers, since the developer would need to know that the base controller should be extended. Right now, this looks like the best solution.
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin\*? Or, is there a better way for the ACL check to never need to be explicitly assigned to every admin controller?
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin*?
No
The most simplest approach you can do is create a base controller such as App\Http\Controllers\Admin\Controller and include the middleware
while all other App\Http\Controllers\Admin\* extends it.
Alternatively, while still adding App\Http\Controllers\Admin\Controller, you could instead inject the middleware through IoC Container.
App::afterResolving('App\Http\Controllers\Admin\Controller', function ($controller) {
$controller->middleware('acl');
});
EDIT
My previous answer didn't quite work for all situations; it broke a lot of other routes. Here's what I ended up doing instead (in app/Http/routes.php):
Route::group(['namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'App\Http\Middleware\Acl'], function()
{
Route::get('/', 'AdminController#index');
Route::get('/user', 'User\UserController#index');
...
});
This at least targets all admin controllers when I define a route. It's not exactly everything I had hope for, but it will do.

Resources