Laravel if route condition not met then ignore - laravel

I have the following 2 routes:
Route::get('/{category}/{slug?}', [CategoryController::class, 'index'])->name('category.index')->where('slug', 'trending|subtitled|feature');
This route
Route::get('/cookies-policy', [PageController::class, 'cookiesPolicy'])->name('cookiesPolicy');
When i try to access the second route, the first route controller is accessed instead.
How do i add a condition to the first route, that if the first segment isn't trending,subtitled or feature then ignore? I thought i accomplished this with: ->where('slug', 'trending|subtitled|feature')

You would need to adjust your where to be assigning the pattern to the category route parameter not the slug parameter:
->where('category', ...);

Related

How to find the parameter name expected in laravel model route binding

I have a route like this
Route::get('/vcs-integrations/{vcs-provider}/authenticate','VcsIntegrationsController#authenticate');
and the method to handle the route I am using the model route binding to happen is as follows
<?php
....
use App\Models\VcsProvider;
....
class VcsIntegrationsController extends Controller
{
public function authenticate(VcsProvider $vcsProvider, Request $request)
{
...
// some logic
...
}
}
when I try to access the route I am getting 404 due to the parameter name is not matching.
So, how do I know the parameter name expected by laravel in route model binding ?
From the route parameter docs:
"Route parameters are always encased within {} braces and should consist of alphabetic characters, and may not contain a - character. Instead of using the - character, use an underscore (_)." - Laravel 7.x Docs - Routing - Route Parameters - Required Parameters
You should be able to define the parameter as {vcs_provider} in the route definition and then use $vcs_provider for the parameter name in the method signature if you would like. You can also name it not using the _ if you prefer, but just avoid the -, hyphen, when naming.
Have fun and good luck.
Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
This means that if you want implicit binding to work, you need to name the route param same as your variable. Since your variable's name is vcsProvider, your route should be:
Route::get('/vcs-integrations/{vcsProvider}/authenticate','VcsIntegrationsController#authenticate');

Laravel two similar routes, second route not found

Laravel 5.8, I have two routes:
Route::get('/exam-info/{id}', 'ExamController#mainExamInfo')->name('main_exam_info');
Route::get('/exam/{id}', 'ExamController#startMainExam')->name('start_main_exam');
When I go to the second route it gives me "page not found" error! Why?
Update:
In ExamController my startMainExam function is:
public function startMainExam($exam_id){
dd("sss");
// other stuff
}
But when I change the second route to:
Route::get('/exaxxxx/{id}', 'ExamController#startMainExam')->name('start_main_exam');
It works!!
Do you defined resource route on ExamContorller. Something similar like below on your route.php
Route::resource('exam', 'ExamController');
If it present, please change the second route name to something else like /exam-id/{id}

Side By Side Static Routes & Wild Card Routes In Laravel

I have a use case for a Laravel website I am working on to have some static routes sitting at the exact same level as the main wild card route.
EG:
Route: /store/cart Static Route
Route: /store/checkout Static Route
Route: /store/* Dynamic Route
Route: /store// Dynamic Route
Route: /* Dynamic Route
Been trying to figure out how to implement this routing structure in Laravel and while the static routing rules work fine as soon as I add the wild card routes I wind up with the wild card route trying to catch the static routes as well.
How would I be able to add routing rules to support this?
change the conflicting routes to non conflicting.
Route: /store/cart Static Route => this is ok
Route: /store/checkout Static Route => this is ok
Route: /store/* Dynamic Route => /store/id/{id}
Route: /store// Dynamic Route => /store
Route: /* Dynamic Route => remove this and be specific by having more routes for the needs
Us global constraint
Route::pattern('all','.*');
Then define your routes in order
Route::('store/cart', function () {});
Route::('store/checkout', function () {});
Route::('store', function () {});
Route::('store/{all}', function ($all) {});
Route::('{all}', function ($all) {});
Managed to get it working.
The first step was to use global constraint route patterns per #Aboalnaga...
Route::pattern('variableName','.*');
Each variable was defined with this route pattern to make it a wild card pattern.
The next step was to ensure route ordering. It appears as though when handling routing Laravel will work its way through the route list in order. As soon as it finds the first matching route it will stop there and run that route. So in order to handle a route chain in the form of domain.com/store/cat-1/productwhere the request could be for domain.com, domain.com/store, domain.com/store/cat-1, domain.com/store/cat-1/product, or domain.com/some-content-page-from-database the route needed to be defined as...
Route::get('/store/shopping-cart', 'onlineStore#showCart');
Route::get('/store/checkout', 'onlineStore#showCheckout');
Route::get('/store/checkout/payment', 'onlineStore#showPayment');
Route::get('/store/checkout/success', 'onlineStore#showPaymentSuccess');
Route::get('/store/checkout/error', 'onlineStore#showPaymentError');
Route::get('/store/{category}', 'onlineStore#showCategory');
Route::get('/store/{category}/{product}', 'onlineStore#showProductDetails');
Route::get('{article}', 'articles#showArticle');
By defining the routes in order and having the variable route defined as the last route at that level the variable route will only be triggered if the preceding routes don't match.

Pass parameter from route to controller in laravel?

I want to pass current agency id from route to controller in laravel 5.2.
ex:- I have one resource controller is AgencyController.
Route::resource('agencies', 'Admin\AgencyController');
I want to add one more route, such as,
Route::get('agencies/me', 'Admin\AgencyController#show', ['middleware' => ['web', 'agency']]);
Here I want to pass agency id from session as default parameter to agencyController#show function.
ex:- Auth::guard('agency')->user()->agencies_id
Is it possible in laravel?
Laravel routes function that if you configure your route like:
Route::get('user/{user}', 'UserController#someMethod');
you can pick up whatever you send after the slash in the controller. So if you call:
www.example.com/user/3
and your controller is like public function someMethod($id) the 3 will be forwarded to $id variable

Laravel routing & filters

I want to build fancy url in my site with these url patterns:
http://domain.com/specialization/eye
http://domain.com/clinic-dr-house
http://domain.com/faq
The first url has a simple route pattern:
Route::get('/specialization/{slug}', 'FrontController#specialization');
The second and the third url refers to two different controller actions:
SiteController#clinic
SiteController#page
I try with this filter:
Route::filter('/{slug}',function()
{
if(Clinic::where('slug',$slug)->count() == 1)
Route::get('/{slug}','FrontController#clinic');
if(Page::where('slug',$slug)->count() == 1)
Route::get('/{slug}','FrontController#page');
});
And I have an Exception... there is a less painful method?
To declare a filter you should use a filter a static name, for example:
Route::filter('filtername',function()
{
// ...
});
Then you may use this filter in your routes like this way:
Route::get('/specialization/{slug}', array('before' => 'filtername', 'uses' => 'FrontController#specialization'));
So, whenever you use http://domain.com/specialization/eye the filter attached to this route will be executed before the route is dispatched. Read more on documentation.
Update: For second and third routes you may check the route parameter in thew filter and do different things depending on the parameter. Also, you may use one method for both urls, technically both urls are identical to one route so use one route and depending on the param, do different things, for example you have following urls:
http://domain.com/clinic-dr-house
http://domain.com/faq
Use a single route for both url, for example, use:
Route::get('/{param}', 'FrontController#common');
Create common method in your FrontController like this:
public function common($param)
{
// Check the param, if param is clinic-dr-house
// the do something or do something else for faq
// or you may use redirect as well
}

Resources