Why my routes are not ordered? - laravel

in my routes file I use a route group with segment like:
Route::group(['prefix' => request()->segment(1) ], function(){
//routes
});
Normally, my routes are in the order they were written at, but when using the group with request()->segment(1) routes just get disarranged (not just inside the group itself, but all of them), I need to use segment so every customer will have their own slug as the first segment in the URL.
so how can I fix this issue?

Use middleware to validate the user and allow them based on their slug
Please Make own middleware like jwt.auth
I developed my own middleware to filter slug based

Related

attach the unique id with the URL cross entire app in Laravel

I have created an application like a portfolio, every user has a unique id or username, I need to generate a copy of this for each user by adding the ID in the URL as a parameter, I know how to do that surly, but I need to attach only with the one Route and then it will still across entire pages and requests for this user? is there any way to do that?
I think I can do it in this way, and then I will store it in the session? is it possible? and is it the best way, because I need the official or professional way
Route::get('/uid', [HomeController::class, 'home'])->name('home');
Let's assuse you want to have theese routes for example
/{uid}/profile
/{uid}/prot
Based on document you can use group to add prefix to all the routes
Route::prefix('/{uid}')->group(function () {
Route::get('/profile', [HomeController::class, 'profile'])->name('profile');
Route::get('/prot', [HomeController::class, 'prot'])->name('prot');
});
Using this you can pass uid across all routes that created in this groups

Links in view files that are called through different named routes

Our team is trying to convert an old multitenant architecture over to Laravel and having some difficulty staying DRY in our routes/views.
Our account section contains multiple page views: an account dashboard, edit profile, payment methods, registrations, etc. However, we provide multiple stand-alone websites for a client, and there are multiple URL structures for the user to access their account:
In addition to the standard...
https://clientone.ourdomain.com/account/
...they can also access their account via different standalone websites:
https://clientone.ourdomain.com/event-app-one/account/
https://clientone.ourdomain.com/event-app-two/account/
All of those URLs above give them the exact same information, but with a different layout/theme applied for each standalone website. Right now the routes I set up for those above look like this:
// #### CLIENT ONE - ROOT
Route::domain('{subdomain}.ourdomain.com')->group(function() {
Route::middleware(['setTheme:clientone-account-theme'])->group(function() {
Route::get('/', 'ClientController#index')->name('index');
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.account.edit');
...
});
});
// #### CLIENT ONE - EVENT APP ONE
Route::prefix('event-app-one')->group(function() {
Route::middleware(['setTheme:clientone-eventapp-one-theme'])->group(function() {
Route::get('/', 'EventAppController#index')->name('clientone.eventapp.one.index');
...
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.eventapp.one.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.eventapp.one.account.edit');
...
});
});
});
// #### CLIENT ONE - EVENT APP TWO
Route::prefix('event-app-2')->group(function() {
Route::middleware(['setTheme:clientone-eventapp-two-theme'])->group(function() {
Route::get('/', 'EventAppController#index')->name('clientone.eventapp.two.index');
...
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.eventapp.two.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.eventapp.two.account.edit');
...
});
});
});
Those routes all currently work. We don't like including the client or app name in all of our route names because they get rather long and can't be reused, but if we take those out we found out our route URLs will override each other.
However, if we do it this way, our account views that we share across all these URLs can't use named route links for href because we don't know which one to use. For example, we can't do this in blade...
Edit Profile
...because, while that will work while at clientone.ourdomain.com/account/, it won't work while at clientone.ourdomain.com/event-app-one/account/.
Should I just not use route names for links in our views and use a relative link instead? Or am I going about my route naming all wrong? The only other thing I can think of is to copy all the view files and have one version for .com/account/ and another for .com/all-event-apps/account/ and just use a different set of route names for each. Feels wrong to duplicate essentially the same functionality in those views though.
You can use a parameter for the prefix so you are not repeating the same exact routes and creating new names for them. You can then generate routes based on those route names.
You can set defaults for parameters for the UrlGenerator to help deal with this.
I would add a middleware to your group that checks the prefix then will assign that as a default parameter on the UrlGenerator:
// instead of app-one, app-two, etc etc
Route::prefix('{app}')->middleware('handleapp')...
// handleapp middleware
Url::defaults(['app' => $request->route()->parameter('app')]);
$request->route()->forgetParameter('app'); // if you dont want this passed into controller methods
// where you need to generate a route
route('eventapp.account.edit'); // {app} is handled by the default we set so doesn't have to be passed
I would also have a middleware that will add the default parameter for subdomain as well so you don't have to pass that yourself everywhere.
Basically it all becomes dynamic and based on the current request you can have defaults setup for all these parameters so you don't have to pass them into the route helpers yourself everywhere you need a URL from a route name.
This is just the basic idea in use.

How do I move a request to API in laravel?

I can't seem to find an answer on the web or maybe I'm missing something.
Let's say my laravel application domain is my-laravel.com
Now I want to make requests at api.my-laravel.com which will work just same as my-laravel.com/api/
How do I do that?
Solution: Changed prefix('api') to domain('api.my-laravel.com') in RouteServiceProvider#mapApiRoutes
You may group your routes in a sub-domain, change your routes/api.php
Route::group(["domain" => "api.domain.key"], function() {
// your api routes.
});
Edit:
Check your RouteServiceProvider then remove the api prefix in mapApiRoutes method.
Alternatively(Except DNS and mod_rewrite)
Sub-Domain Routing
Route groups may also be used to handle sub-domain routing. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified by calling the the domain method before defining the group:
Route::domain('{account}.myapp.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Source: https://laravel.com/docs/5.4/routing#route-group-sub-domain-routing
Note:
Before this map your subdomain to point your server and point your domain (laravel.com)

Laravel: Automatically add parameter to urls

I have an application in which you can create a service and a service can have its own partial view.
So I created a route group with {service} prefix:
Route::group(['prefix' => '{service}', ... ], ... ).
// http://.../my-service/my-url
However, in order to know in which service the user is I need to add the service in every single route I have in my application. So I have done a middleware that shares $service to every view:
view()->share(['service' => $service])
But I don't know how to add $service prefix to every route without explicitly adding it. I would like doing something like
route()->prefix(['service' => $service])
and then every route have the prefix $service:
url("myurl") // -> url("$service/my-url") or
route('my-route')
Any idea?
EDIT:
Finally I decided to create a ServiceType model, create a middleware with a parameter and set to my route groups. Then in view I offer the user to switch between services of the same type.
Not is what I was looking but it's OK for now.
Question is still open if anyone knows the answer.
Put all your routes you want prefixed in a group and then add the prefix
Laravel docs on route prefixes

laravel advanced routing to multiple controllers

I have in a middleware those two routes so they stay on top of all other routes
Route::get('{slug?}', array(
'as' => 'homeIndex',
'uses' => 'Modules\\Pages\\Controllers\\Pages#index'
))->where('slug', '(.*)?');
Route::get('{company?}', array(
'as' => 'companyProfile',
'uses' => 'Modules\\Company\\Controllers\\Profile#index'
))->where('company', '(.*)?');
what I'm trying to achieve is route all pages through homeIndex and all companies profile through companyProfile all on the first segment.
Is working fine for pages, but for companies profile I get 404.
It's same like facebook if you go on facebook.com/about the result is about page if you replace about with your unique name you get your profile.
Any ideas how to make it work?
Facebook works because about is a route. This works because your unique name can never be about. So they look for the about route first, and if the segment isn't about, they know it's probably a unique name.
Yours is different because your app doesn't know if your first segment is a slug or a company so you need some way to tell it the difference. If you redirected everything to a single function, then in that function did some queries or whatever you need to do to figure out if the first segment is a slug or a company name, then redirect that appropriately, it would work.
Laravel reads routes from the top to the bottom. When you hit the route /some-random-company, Laravel has no idea this is a company. All it knows is it happens to match the first route so it hits the slug route with your company. So another solution would be to update the wheres on your routes so Laravel has some idea if the incoming route parameter is a slug or a company and will know where to route that request to.
I'm terrible at regular expressions and I don't know how you are making slugs or if there is any rules you have setup on what a company name can or can not consist of. What you would have to do is figure out if there is anyway where you can accurately determine if the route parameter is a slug or company. For example, if it has one or more of -, it might be a slug.
Then you'd have to write a regular expression pattern to look for multiple - and then put that pattern into the where for the slug route. Then if the route parameter is a company and it does not match that pattern which was looking for one or more of -, Laravel will know to match this request with the company route.
If there is nothing which you can use to determine if a string is a slug or a company, you will have to update your routes so it looks like company/{company?} and slug/{slug?} and then output your links appropriately. This way Laravel will know for sure where to route that traffic.

Resources