Laravel pass a certain parameter to all routes in all views - php

I needed to pass a subdomain name to all views so that when they generate routes with route('namedRoute') users will end up in the same subdomain.
I ended up creating a ViewServiceProvider which registers a view composer where I get the subdomain from the request like so:
use Illuminate\Support\Facades\View as FView;
use Illuminate\View\View;
class ViewServiceProvider extends ServiceProvider {
FView::composer('*', function(View $view){
$view->with('subdomain', request()->route()->subdomain);
});
}
This way the subdomain variable will be passed to every singe view every time thanks to the '*' as documented in Laravel docs.
Then when I need to generate any route in any view, I will always have to pass the subdomain like so and the route will be generated correctly.
{{ route('signInPage', ['subdomain' => $subdomain]) }}
So is there something in laravel (like a post view processing) that I can hook into to populate the subdomain automatically so I don't have to now modify every route generation in every view?

The URL generator can take defaults so you don't have to pass a paremeter for the route when generating the URL:
URL::defaults(['subdomain' => ....]);
You can create a route middleware that gets the subdomain parameter from the request and sets this default.
Laravel 8.x Docs - URLs - Default Values

Related

What are some use cases of Named Routes in Laravel?

After reading the documentation, I still only have a vague idea of what Named Routes are in Laravel.
Could you help me understand?
Route::get('user/profile', function () {
//
})->name('profile');
Route::get('user/profile', 'UserProfileController#show')->name('profile');
It says:
Once you have assigned a name to a given route, you may use the route's name when generating URLs or redirects via the global route function
I don't understand what the second part of the sentence means, about generating URLs or redirects.
What would be a generated URL in the case of profile from the above example? How would I use it?
The best resource is right here : https://laravel.com/docs/5.8/routing#named-routes
One of the common use case is in your views. Say your post request goes to a particular route, basically without named routes you can simply go like this to store a task
action="/task"
but say for example you need to update the route to /task/store , you will need to update it everywhere you use the route.
But consider you used a named route
Route::post('/task', 'TaskController#store')->name('task.store');
With named routes you can use the route like this in your view:
action="{{route('task.store')}}"
Now if you choose to update your route, you only need to make the change in the routes file and update it to whatever you need.
Route::post('/task/now/go/here', 'TaskController#store')->name('task.store');
If you need to pass arguments to your routes, you pass it as arguments to route helper like this:
route('task.edit', 1), // in resource specific example it will output /task/1/edit
All of the view examples are given you use blade templating.
After adding a name to a route, you can use the route() helper to create urls.
This can now be used in your application.
For instance, in your blade templates this may look like:
{{ route('profile') }}
This will use the application url and the route path to create a url.
this is how it looks it:
named route sample name('store');:
Route::get('/store-record','YourController#function')->name('store');
store is the named route here. to call it use route('store')
defining another type of route. this is not named route:
Route::get('/store-record','YourController#function')
you can access this route using {{ url('/store-record') }}
hope this helps

Laravel Forwarding Route To Another Route File

I'm building enterprise modular Laravel web application but I'm having a small problem.
I would like to have it so that if someone goes to the /api/*/ route (/api/ is a route group) that it will go to an InputController. the first variable next to /api/ will be the module name that the api is requesting info from. So lets say for example: /api/phonefinder/find
In this case, when someone hit's this route, it will go to InputController, verifiy if the module 'phonefinder' exists, then sends anything after the /api/phonefinder to the correct routes file in that module's folder (In this case the '/find' Route..)
So:
/api/phonefinder/find - Go to input controller and verify if phonefinder module exists (Always go to InputController even if its another module instead of phonefinder)
/find - Then call the /find route inside folder Modules/phonefinder/routes.php
Any idea's on how to achieve this?
Middlewares are designed for this purpose. You can create a middleware by typing
php artisan make:middleware MiddlewareName
It will create a middleware named 'MiddlewareName' under namespace App\Http\Middleware; path.
In this middleware, write your controls in the handle function. It should return $next($request); Dont change this part.
In your Http\Kernel.php file, go to $routeMiddleware variable and add this line:
'middleware_name' => \App\Http\Middleware\MiddlewareName::class,
And finally, go to your web.php file and set the middleware. An example can be given as:
Route::middleware(['middleware_name'])->group(function () {
Route::prefix('api')->group(function () {
Route::get('/phonefinder', 'SomeController#someMethod');
});
});
Whenever you call api/phonefinder endpoint, it will go to the Middleware first.
What you are looking for is HMVC, where you can send internal route requests, but Laravel doesn't support it.
If you want to have one access point for your modular application then you should declare it like this (for example):
Route::any('api/{module}/{action}', 'InputController#moduleAction');
Then in your moduleAction($module, $action) you can process it accordingly, initialize needed module and call it's action with all attached data. Implement your own Module class the way you need and work from there.
Laravel doesn't support HMVC, you can't have one general route using other internal routes. And if those routes (/find in your case) are not internal and can be publicly accessed then also having one general route makes no sense.

Laravel call controller based upon query string or post variables

I am creating APIs for an app. Now app developer wants me to create a fixed base url and pass the ROUTE NAME (Which will point to controller function) as POST variable. Example:
http://example.com/Api
and POST variables like:
action=>'ROUTE_NAME'
But in laravel we can define the routes based upon the url parts as:
http://example.com/Api/ROUTE_NAME
I have tried using a single controller and loading the other controllers based upon SWITCH statements. But that doesn't seem to be a standard practice as i need to add switch condition every time I'll create a new API. Also middleware will not work on the loaded controllers dynamically.
Is there a way in laravel to achieve this? I am using laravel 5.4
You could implement a middleware that listens on the /Api route, which gets the ROUTE_NAME from the $request, then you could use the Route() helper function to find the url of that named route, then redirect the request to that route.
Something like:
// Generating ROUTE_NAME url...
$url = route($request->route_name);
// Redirect to that route...
return redirect()->route($url);
Obviously you'll need to add code to handle if it doesn't find a route etc, maybe return a json response back with a proper error code etc.

Laravel route to controller not working

I'm trying to add a new controller to an existing laravel project. The application already has some pages at /users and I am trying to add a RESTful API which works separately to this. I would like the API to be available at api/users.
I have created the controller using PHP artisan:
php artisan controller:make ApiUsersController
I have added the following to my routes:
Route::controller('api/users', 'ApiUsersController');
However when I hit the URL I just receive the site's 'Page could not be found' message.
Is there something I have missed?
It looks like the issue you're having is that you've used Route::controller rather than Route::resource.
Route::resource maps routes to the seven RESTful methods that the controller generator creates by default. Route::controller maps them to methods that you add yourself that have the HTTP method as part of their name, in your case if you had a method called getIndex it would be called on a GET request to /api/users/index or if you had one called postStore it would be called on a POST request to /api/users/store.
In order to add the API prefix to the route you could use the following:
Route::group(['prefix' => 'api'], function() {
Route::resource('users', 'ControllerName');
});
You could also add any other controllers in the API within the same callback.

Create a single route for every controller and method in Laravel

Can I set a default route, so when I have a request like /home/index and /home, it would redirect to the home controller's index action, just like in other frameworks?
I know that I can set them one by one but I don't want to add a route for every request, I would like to use only one route for all requests.
Theres two other types of controllers beside the basic controller. You can create these by specifying a special route to your controller. With this technique you don't have to create a route for every method just one per controller.
Resource Controller
This will create all the methods with the corresponding HTTP verb you need for managing one resource like a user or a product. There is a table in the documentation that contains which predefined route matches the predefined methods of the controller, that represents an action you can do with a method, like edit, create, destroy, etc:
Anyway, you still free to add extra methods and routes beside the resource controller methods and routes, just keep in mind that you have to do this before defining the resource controller route:
//Extra route for the resource controller.
Route::get('home/profile', 'HomeController#profile');
//Resource controller routes.
Route::resource('home', 'HomeController');
RESTful Controllers
I think this is what will fit better for your needs.
Creating a RESTful controller will automatically create a route for all methods that begins with a HTTP verb.
Route::controller('home', 'HomeController');
After this, you can create methods like these in your HomeController:
public function getIndex() {
//Code.
}
public function postProfile() {
//Code.
}
The framework will automatically create the routes for them, so you can access postProfile() through a HTTP POST to the /home/profile route. Also you can access getIndex() through a HTTP GET to the /home/index.
The documentation also mentions:
The index methods will respond to the root URI handled by the controller.
In our case that means that you can acces your getIndex() method through the /home/index and the /home routes too.
If you have a method that has multiple words in it (a word start with a camel case letter), then the generated route will have a - between the words, so the method getAdminProfile() will have a route called home/admin-profile.
Also as I told at the resource controller section, you can still create regular routes, just be sure to create them before you create the RESTful controller's route.
Final answer
Create a route: Route::controller('home', 'HomeController'); call your root method getIndex() and prefix every other method with a HTTP verb e.g. userTool() should become getUserTools().
If you're using Route::controller() just name your index() method getIndex().

Categories