Escape forward slash in laravel - php

I have dozens of routes like the following list
Route::group([
'where' => ['aNumber' => '.*'],
], function () {
Route::get('air/{aNumber}/tools', 'AirController#tools');
Route::post('air/{aNumber}/handled', 'AirController#handled');
Route::post('air/{aNumber}/notHandled', 'AirController#notHandled');
Route::get('air/{aNumber}/act', 'AirController#act');
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
Route::get('air/{aNumber}', 'AirController#show');
});
the {anumber} parameter could be like these 23-349493/4 While this kind of parameter will produce some conflicts with other routes, So for example if we are going to call air/28-23422/sendAct then instead of calling #sendAct route, it'll call #show.
because laravel thinks that /sendAct is part of the parameter. Well, I can fix this problem by adding more where not(Regex) on each of the routes and define the logic that every route should follow, But do you have a better solution for this problem?

No, you are wrong, Laravel will choose show since air/28-23422/sendAct won't hit sendAct because sendAct has as supposed method POST, and not GET.
Instead of:
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
try writing
Route::get('air/{aNumber}/sendAct', 'AirController#sendAct');
// ^^^
Or use ^[^\/]* as where clause of the group for aNumber

Related

Named route is not defined in Laravel 8

Instead of redirecting, I'm receiving the error below. Why?
Route [moderator.products] not defined.
These are my routes in a middleware's group function:
Route::get('moderator/products', [ModeratorController::class, 'products'])
->name('moderator.products');
Route::redirect('/', route('moderator.products'));
The issue can be resolved by naming the route first without chaining it at the end.
Route::name('moderator.products')->get('moderator/products', [ModeratorController::class, 'products']);
Route::redirect('/', route('moderator.products'));
I tested them. It reidrects to the mentioned named route. All you need to do is to first call the name() then chain the get().
Not an answer, but I got around this by not using the named route, and using the url, i.e. swap route('moderator.products') for url('moderator/products').
EDIT: I did a bunch of code editing to get past my problem, so I'm not sure, but I suspect my issue was caused by naming the exact same route twice. Double check to make sure you haven't done this if you get this problem.

Laravel how to generate urls using GET route names?

I got this 2 routes in my routes file (web)
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
Route::post('management/special-fees/add', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
They both share the same name but one is GET and the other is POST, so far so good. But now I want to make an url in my view to open the form, for that I use the method route() like this
route('management/special-fees/add',$user->id )
but when trying to go to the url I get this route
.../management/special-fees/add?5
there is a question mark instead of a "/" so the route is invalid.
I made some tests and I figured out that happens because is trying to go to the POST route instead of the GET one if I change the POST route's url in the web file like this
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
Route::post('management/special-fees/addSSSS', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
I will in fact get this url
.../management/special-fees/addSSSS?5
So why is the route() method generating a url for the POST route over the GET one? how do I make it to choose the GET route first?
In laravel the routing is prioritized by in the order it is written in your route.php file.
In this case you're writing the Route::post last, which in turn tells Laravel that that one should have the highest priority. Try switching them and the Route::get will have the higher priority.
Like so:
Route::post('management/special-fees/addSSSS', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
I may be wrong, but I think you'll have to re-think route naming. One of the problems route naming helps eliminate is redundant and complex names. For example, if you looked at route:list for Route::resource('something', 'SomethingController') it will have something.index, something.store as route names for Route::get('something') and Route::post('something').
If it's the same name, it will always resolve to the first one and will probably never hit the second route; in your case will hit the POST route and never the GET route.
?5 means 5 is an argument for your get route.
try this
url('management/special-fees/add/'.$user->id)
for get route insted of
route('management/special-fees/add',$user->id )

How to use optional route parameters properly with Laravel 5.6?

I am trying to create an API with Laravel 5.6, however, it seems to me that it's not possible to use optional route parameters before/after the parameter.
I'd like to achieve the following:
Route::get('api/lists/{id?}/items',
[
'as' => 'api/lists/items/get',
'uses' => 'ListsController#getListItems'
]);
With the above scenario, if I'm trying to visit api/lists/1/items it shows the page. On the other hand, if I'm trying to visit api/lists/items it says that the page is not found.
What I basically want is if there's no List ID specified, Laravel should fetch all the List ID's items, otherwise it should only fetch the specific ID's items.
Q: How is it possible to the optional parameter in between the 'route words'? Is it even possible? Or is there an alternative solution to this?
As far as I know, it's not possible to use optional parameters in the middle of your url.
You could try a workaround by allowing 0 for the optional parameter and loading all items in this case, as described here.
However, I'd recommend going with two different routes here to match everything you want:
api/lists/items
api/lists/{id?}/items
You have to give default value for optional parameter in the controller:
Route
Route::get('api/lists/{id?}/items', 'ListsController#getListItems');
ListsController
public function getListItems($id = null) {
---your code----
}
Reference

Laravel named routes parameter not working correctly

I'm currently using Laravel 5.3 and i have a number of routes similar to.
Route::get('/news/create/{product}', 'NewsController#create')->name('news::create');
So in my blade template im using the route() function like so:
{{route('news::create','car')}}
But the url generated is
/news/create?car
not the required
/news/create/car
The same thing happens if i put it in an array:
{{route('news::create',['car'])}}
And if i give it a key like so:
{{route('news::create',['product'=>'car'])}}
I get:
/news/create?product=car
How do I get the correct url so it is passed to the 'create' function as a parameter?
Firstly, take a look at your route naming. I don't think there's anything specifically wrong with naming a route like 'news::create' apart from it being ugly and quite probably considered bad practice. I like to go with camel casing, which means I'd use a name like createNews. It's much easier when going back to work on old sections of code and will stop other programmers from stabbing you if/when they work on a project with you.
The reason we can name routes is so that the name stays static even if we change the route URI or controller endpoint. We can pass variables to it using route parameters.
Route::get('/news/create/{product}', array('as' => 'createNews', 'uses' => 'NewsController#create'));
route('createNews', ['product' => 'car']);
{{route('news::create',['product => 'car'])}}
Should fix your problem. Laravel uses named routes and expects an array with the keys as names with values.
Read all about it here: https://laravel.com/docs/5.3/redirects#redirecting-named-routes

Route group with optional parameter

I'm wondering if it is possible to use optional parameters in a group prefix.
Using it with {parameter?} like in any other route doesn't work:
Route::group(array('prefix' => 'foo/{foo_id?}'), function() {
Route::any('bar', 'ApiFooController#bar');
});
I would like to catch both foo/bar and foo/2/bar.
As much as I can see, it only works without the questionmark but then foo/bar(without the parameter) throws an error.
I would like to avoid defining two seperate groups which would be a workaround. Maybe Important to note: bar is a custom function in addition to a resource so I'm not trying to define a resource (like foo.bar).
I think you might have to define the route twice, but you don't have to create another group.
Does this work for you?
Route::group(array('prefix'=>'foo'),function() {
Route::any('bar', 'ApiFooController#bar');
Route::any('{foo_id}/bar', 'ApiFooController#bar');
});

Categories