Laravel 5.1 adding middleware to resource route - php

so I have been trying to use middleware with my route resource and having trouble making it work.
Here is my routes setup:
Route::group(['prefix' => 'api','middleware' => 'locationRouteValidator'], function()
{
Route::resource('location', 'LocationController');
});
and route seems to be setup properly:
php artisan route:list
+--------+----------+------------------------------+----------------------+-------------------------------------------------+------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------------+----------------------+-------------------------------------------------+------------------------+
| | GET|HEAD | / | | Closure | |
| | GET|HEAD | api/location | api.location.index | App\Http\Controllers\LocationController#index | locationRouteValidator |
| | POST | api/location | api.location.store | App\Http\Controllers\LocationController#store | locationRouteValidator |
| | GET|HEAD | api/location/create | api.location.create | App\Http\Controllers\LocationController#create | locationRouteValidator |
| | DELETE | api/location/{location} | api.location.destroy | App\Http\Controllers\LocationController#destroy | locationRouteValidator |
| | PATCH | api/location/{location} | | App\Http\Controllers\LocationController#update | locationRouteValidator |
| | GET|HEAD | api/location/{location} | api.location.show | App\Http\Controllers\LocationController#show | locationRouteValidator |
| | PUT | api/location/{location} | api.location.update | App\Http\Controllers\LocationController#update | locationRouteValidator |
| | GET|HEAD | api/location/{location}/edit | api.location.edit | App\Http\Controllers\LocationController#edit | locationRouteValidator |
+--------+----------+------------------------------+----------------------+-------------------------------------------------+------------------------+
so now I create the middleware :
php artisan make:middleware locationRouteValidator
and leave the default code, which is :
public function handle($request, Closure $next)
{
return $next($request);
}
and just for testing, in my controllers show method, I echo out the passed id like so:
public function show($id)
{
//
echo "show ".$id;
}
so now I expect that when I visit /public/api/location/abcd it should display:
show abcd or when I visit /public/api/location/1234 it should display show 1234 after which I intended to modify the middleware to allow only numeric values to be passed into {location}.
But If I just run with the default middleware code, the page returns white without displaying anything. I remove the middleware from the route, and it displays the text as expected.
I know I could attach the middleware to the controller instead, but I thought of attaching it in the route instead so that I could write and apply some common middleware by using the route's group feature, which should be possible, right?
Where do you guys think I am going wrong? Thanks in advance for looking!

Check your \app\http\kernel.php file to see if you have registered the middleware as a route middleware.

Related

Framework PHP Route - Error 404 Not found

In Laravel, I need to edit user created by Auth/RegisterController, but using the controller that I created, example ProfileController. But when I try access by a a:href button, show 404 Error.
Code:
web.php
Route::group(['middleware' => ['auth']], function(){
Route::resource('profile', 'ProfileController')->except(['edit']);
Route::get('profile/{profile}/edit', ['as' => 'profile.edit', 'uses' => 'ProfileController#edit']);
});
Auth::routes();
app.blade.php
<a href="{{route('profile.edit',['profile'=>auth()->user()->id])}}" class="btn btn-primary">
{{auth()->user()->email}}
</a>
ProfileController
public function edit($profile)
{
$user = \App\User::findOrFail($profile);
return view('profile.edit', compact('user'));
}
List Routes
| | POST | profile | profile.store | App\Http\Controllers\ProfileController#store | web,auth,guest |
| | GET|HEAD | profile | profile.index | App\Http\Controllers\ProfileController#index | web,auth,guest |
| | GET|HEAD | profile/create | profile.create | App\Http\Controllers\ProfileController#create | web,auth,guest |
| | DELETE | profile/{profile} | profile.destroy | App\Http\Controllers\ProfileController#destroy | web,auth,guest |
| | PUT|PATCH | profile/{profile} | profile.update | App\Http\Controllers\ProfileController#update | web,auth,guest |
| | GET|HEAD | profile/{profile} | profile.show | App\Http\Controllers\ProfileController#show | web,auth,guest |
| | GET|HEAD | profile/{profile}/edit | profile.edit | App\Http\Controllers\ProfileController#edit | web,auth,guest |
Someone can help me?
Tks,
Aguiar, Adson M.
Welcome to SO!
Like #lagbox mentioned, you can just keep the
Route::resource('profile', 'ProfileController');
without the ->except() to have the exact same edit route automatically generated for you.
Furthermore, you can simplify your controller action to:
public function edit(User $profile)
{
return view('profile.edit', compact('profile'));
}
This uses type hinting to automatically have the dependency injection resolve a User instance for you, identified by the key passed in with the {profile} parameter.
You would then have to go with $profile in your profile/edit.blade.php, unless you want to do something like return view('profile.edit', ['user' => $profile]);.
It might be a good idea to name the parameters like your Models. Resource routes usually base completely on the Model's names, so profile is not a good choice for User routes. You might either use Route::resource('user', 'ProfileController') (or even UserController for that matter), or if you want to stick with profile, but want $user as a parameter, you would have to create all routes by yourself like Route::get('profile/{user}/edit', 'ProfileController').
Also, writing route('profile.edit',['profile'=>auth()->user()]) works too, and has the advantage that it would not break when the user is not authenticated.
All that said, your code should still work. Try to use a find() instead of a findOrFail() and dd($user); in the following line to make sure your route is working. If you see the dump, it is probably null, meaning the id passed is not valid, which would be really odd.
If you can post the full generated link of the anchor tag and the outcome of the dd, I'll be happy to help.

Why does route requirements works for my first route and not for my second one?

I got this issue :
My first route disallow me of using any character that isn't a number (from the regex), this is perfectly working (tell me if you need screen of the result)
But the second one let me use any character as an id, I don't get why, I've tried clearing cache (and many other things) but it stills allow me to use alpha characters.
I have theses two routes currently :
<?php
// src/Controller/AdvertController.php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Twig\Environment;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* #Route("/advert")
*/
class AdvertController extends AbstractController
{
/**
* #Route("/{page}", name="oc_advert_index", requirements={"page" = "\d+"}, defaults={"page" = 1})
*/
public function index(Environment $twig, $page)
{
$content = $twig->render('Advert/index.html.twig', ['page' => $page, 'name' => 'alex']);
return new Response($content);
}
/**
* #Route("/view/{id}", name="oc_advert_view", requirements={"id" = "\d+"})
*/
public function view(Environment $twig, $id)
{
$content = $twig->render('Advert/view.html.twig', ['id' => $id, 'name' => 'alex']);
return new Response($content);
}
}
My templates are basic Twig templates (displaying either "id" or "page")
I've tried to look for hidden space and something but I can't find where is the difference (excluding the names "id" and "page")
EDIT1 : here what's I got when executing php bin/console router/match /advert/view/abc:
[OK] Route "oc_advert_view" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | oc_advert_view |
| Path | /advert/view/{id} |
| Path Regex | #^/advert/view/(?P<id>[^/]++)$#sDu |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | ANY |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\AdvertController::view |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | utf8: true |
+--------------+---------------------------------------------------------+
It seems that the "Requirements" are not detected/used for some reason, does someone know why ?
EDIT2: Here what I got when doing php bin/console router:match /advert/123
[OK] Route "oc_advert_index" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | oc_advert_index |
| Path | /advert/{page} |
| Path Regex | #^/advert(?:/(?P<page>\d+))?$#sDu |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | ANY |
| Requirements | page: \d+ |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\AdvertController::index |
| | page: 1 |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | utf8: true |
+--------------+---------------------------------------------------------+
Here we can see that it detects the regex, it feels like this is a typo error but I have copy/pasted at least 3 times, very weird :/
FINAL EDIT:
Thank you to every person who tried to find the issue, I learned a few things so I am very thankful (and sorry for the time waste^^)
RESOLVED : There were conflicts between config/routes.yaml and my routes, I had to delete the duplicated route. (I followed a course where we first declare it in config/routes.yaml and then we declare routes with annotations, forgot the step of deleting content of config/routes.yaml)
Thank you to every person who tried to find the issue, I learned a few things so I am very thankful (and sorry for the time waste^^)

Route [invitations.store] not defined. (View: C:\xampp\htdocs\laravel-jobs\resources\views\jobs\show.blade.php). How to fix?

I'm trying to create a pop-up like in the following image:
But I'm getting an error in the line shown below.
This is my file show.blade.php:
<!-- this line produces the error -->
<a href="{!! route('invitations.store') !!}" class="btn btn-danger" onclick="event.preventDefault() >
Apply now
</a>
You need to have a route named invitations.store defined in your routes file, most likely routes/web.php file
This is just an example, make sure to use your proper controller and method name
Route::post('invite', 'InvitationsController#store')->name('invitations.store');
Replace InvitationsController by your controller class name and store by the method in that controller, you can also change invite by another URL you like
Note
If you have created a resource route for a model named Invitation like this
Route::resource('invitations', 'InvitationsController');
You're gonna have routes setup like this
+-----------+-------------------------------+---------------------+----------------------------------------------------+
| Method | URI | Name | Action |
+-----------+-------------------------------+---------------------+----------------------------------------------------+
| GET|HEAD | invitations | invitations.index | App\Http\Controllers\InvitationsController#index |
| POST | invitations | invitations.store | App\Http\Controllers\InvitationsController#store |
| GET|HEAD | invitations/create | invitations.create | App\Http\Controllers\InvitationsController#create |
| GET|HEAD | invitations/{invitation} | invitations.show | App\Http\Controllers\InvitationsController#show |
| PUT|PATCH | invitations/{invitation} | invitations.update | App\Http\Controllers\InvitationsController#update |
| DELETE | invitations/{invitation} | invitations.destroy | App\Http\Controllers\InvitationsController#destroy |
| GET|HEAD | invitations/{invitation}/edit | invitations.edit | App\Http\Controllers\InvitationsController#edit |
+-----------+-------------------------------+---------------------+----------------------------------------------------+
Another note, don't use {!! !!}} to render the route URL, it can be dangerous if an attacker injected something malicious, use {{ }} instead
<a href="{{ route('invitations.store') }}" class="btn btn-danger" onclick="event.preventDefault() >
Hope this helps

Laravel route allow any parameter not working

Any help why this is not working,I am using Laravel 5.4 version ,this is are my routes
app\Providers\RouteServiceProvider.php
public function map()
{
$this->mapWebRoutes();
$this->mapExampleRoutes();
}
protected function mapExampleRoutes()
{
Route::prefix('example')
->middleware('example')
->namespace($this->namespace.'\\Examle')
->group(base_path('routes/example.php'));
}
routes\example.php
Route::get('/{any}', function () {
return view('example.app');
})->where('any', '.*');
$ php artisan route:list
+--------+-----------+-----------------+------+----------+-------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+-----------------+------+----------+-------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | example/{any} | | Closure | example |
+--------+-----------+-----------------+------+----------+-------------+
The problem is when I try to access /example it returns not found (NotFoundHttpException) ,
other routes are working , for example, /example/login .
any idea why this one is not working ?
Route::get('{any?}', function () {
return view('example.app');
})->where('any', '.*');
I removed the leading slash (/) and added a question mark (?) to indicate the slug is optional.

Laravel Using controller Route

i have resource in route and that work correctly and i want to change that to Route::controller.
but after define that i get error in php artisan route :
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
| | GET index | index | Closure | | |
| | GET admin/index | dashboard | Closure | | |
| | GET logout | logout | Closure | | |
| | POST auth | auth | Closure | csrf | |
| | GET login | login | Closure | | |
| | GET admin/admin/profile/{_missing} | | ProfileController#missingMethod | | |
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
my Current route is:
Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
and i want to change that to :
Route::controller('admin/profile', 'ProfileController', array('index'=>'profile.index') );
how to resolve this problem?
This is not an error, Resource and Controller routes are completely different things.
Resource routes have a predefined list of routes (index, create, store, delete, update). If you don't have the method set in your controller it will still work, unless someone hit that route.
Controller routes relies on your controller methods:
public function getIndex() {}
public function getCreate() {}
public function postStore() {}
Methods names are predefined as
<http method><your action name>()
If those methods are not present in your controller, Laravel will not show them in your routes list.
So, just create a
public function getIndex() {}
In your controller and run
php artisan route
Again.
Use :
Route::resource('profile, 'ProfileController', array('as' => 'profile', 'names' => array('index' => 'profile.index')));
Instead of either the routes above.

Categories