Cannot use Auth::routes(); outside default routes/web.php - laravel

I have a simple app with a Group in RouteServiceProvider..
// Web routes
protected function mapWebRoutes()
{
Route::group(['domain' => 'example.com']), function()
{
Route::middleware('web')
->namespace($this->namespace);
->group(base_path('routes/web.php'));
});
// Match any other domains or subdomains
Route::group(['domain' => '{domain}'], function()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/org.php'));
});
}
In routes/web.php i can call Auth::routes(); fine;
but in routes/org.php i get a missing required parameters from my views that need the named auth routes (made by default laravel)
"Missing required parameters for [Route: login] [URI: login]. (View: .../resources/views/layouts/loginmenu.blade.php) (View: .."

Issue was not the Auth::routes function but the fact that the {domain} wildcard did not set a domain in the routes (as it would without the wildcard)
To use default auth routes naming conventions you must update the views to include the domain parameter next to the name.
example:
{{ route('login') }}
needs to be
{{ route('login', ['domain'=>$domain]) }}
Of couse you must make the Domain variable available in views. The easiest way (instead of passing it around the controller like a maniac is to simply share the domain variable with the view.
In my middleware in the constructor of my Controller i call:
view()->share('domain', $domain);

Related

Where are these routes names set in Laravel?

Netbeans isn't showing where the Auth::routes(); is, ctrl+clicking on it, and I'm trying to see why this
<a href="{{ route('register') }}">
works but my own route in web.php does not work. Where is this file setting these? I assume this is a more proper way to set the url because /mynameroute could possibly not work if sites were within some sub directory in different environments?
Auth::routes() is Route::auth() which is Illuminate\Routing\Router#auth. It isn't setting these routes in any special way; you could define them yourself if you wanted to.
For generating URLs there are multiple functions you can use depending on what you need:
Laravel 6.x Docs - URL Generation
All Auth::routes() is declared or works from /vendor/laravel/framework/src/Illuminate/Routing/Router.php files's auth() method you can see there
public function auth()
{
// Authentication Routes...
$this->get('login', 'Auth\LoginController#showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController#login');
$this->post('logout', 'Auth\LoginController#logout')->name('logout');
// Registration Routes...
$this->get('register', 'Auth\RegisterController#showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController#register');
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController#sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController#reset');
}

Laravel - passing route parameter to blade

I am using Laravel 5.6, with the default make:auth mechanism.
In the routes/web.php, I would like to add a language middleware as follow:-
Route::prefix('{lang}')->group(function () {
Route::get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.request');
});
Now I wish to apply this in blade:-
<a href="{{ route('password.request') }}">
But debugger just say:-
Missing required parameters for [Route: password.request] [URI: {lang}/password/reset].
I believe the blade cannot not get the {lang} from route. How can it be achieved?
Try this
<a href="{{ url('en') }}/password/reset">
When you pass a prefix in the route it means that it is going to be included in the route, so when you say
Route::prefix('{lang}')->group(function () {
Route::get('password/reset' .......
Route::get('foo/bar' .......
it means the route will be like this "http://yourwebsite.com/{lang}/password/reset"
"http://yourwebsite.com/{lang}/foo/bar"
so each time you pass any route that falls in that group will need to have a variable called $lang so the link can be initialized.
so in your case
<a href="{{ route('password.request', ['lang' => 'en']) }}"> //you can change en to your preferred language.
if you want to add a middleware to specific route or route group, it is passed in this way
Route::get('/', function () {
//
})->middleware('first', 'second');
or
Route::group(['middleware' => ['first']], function () {
//
});
if you want to create another language, you can check the below links:
Laravel localization
spatie/laravel-translation-loader

Laravel sub-domain routing set global para for route() helper

I have setup sub-domain routing on my app (using Laravel 5.4) with the following web.php route:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('/locations' , 'LocationController');
// Services
Route::resource('/services' , 'ServiceController');
});
However as my show and edit endpoints require an ID to be passed, using a normal route('services.show') helper results in an ErrorException stating Missing required parameters for [Route: services.create] [URI: services/create].
I appreciate this is necessary, but as the company is associated to the user on login (and is in the sub-domain) I don't want to be passing this for every view. I want to set this at a global level.
To avoid repeated queries, I thought about storing this in the session as so (in the :
protected function authenticated(Request $request, $user)
{
$current_company = $user->companies->first();
$company = [
'id' => $current_company->id,
'name' => $current_company->name,
'display_name' => $current_company->display_name
];
$request->session()->put('company', $company);
}
Which is fine, but I wonder if I can pass this to the route as a middleware or something. What's be best solution here?
Recommendation: remove the slash before the resource name.
The resource method will produce the following URIs:
/services/{service}
So, you should define your routes like this:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('locations' , 'LocationController');
// Services
Route::resource('services' , 'ServiceController', ['only' => ['index', 'store']]);
Route::get('services');
});
I ran into this exact issue today, I poked around in the source and found a defaults method on the url generator that allows you to set global default route parameters like so:
app('url')->defaults(['yourGlobalRouteParameter' => $value]);
This will merge in whatever value(s) you specify into the global default parameters for the route url generator to use.

Resolve duplicate routes based on middleware group

In web.php I have two middleware groups for two user roles - admins and non_admins:
Route::group(['middleware' => ['auth', 'admin']], function () {
// if user is logged in AND has a role of admin...
Route::get('/', 'Admin\IndexController#index');
});
Route::group(['middleware' => ['auth', 'non_admin']], function () {
// if user is logged in AND has a role of non_admin
Route::get('/', 'NonAdmin\IndexController#index');
});
Both admin and non_admin middleware check that the role of Auth::user() is admin or non_admin respectively; if it's not, the middleware fails with abort(403). Why do I not have a single middleware? The point of this to separate the two roles, so that each has its own independent controller logic and its own views.
Problem
If I log in as an admin I get 403, if I log in as a non_admin, it works as expected. My guess: Laravel sees the two duplicate routes, and only resolves the one that is defined last (which happens to be in ['middleware' => ['auth', 'non_admin']]).
Question
How do I resolve duplicate routes but separate controller and presentation logic? Again, admin and non_admin users will visit the same route ('/') but see two different views. I also want to implement this in two different controllers.
Hmmm....
I would personally keep everything encapsulated under a common controller, and perform the necessary checks and modifications using a service class.
But if you really want to keep everything separated under two different controllers based on your roles, you could do it this way. This assumes that you're using Laravel's built-in Authorization:
routes
Route::group(['middleware' => ['auth']], function () {
Route::get('/', function(){
$isAdmin = Auth::user()->can('do-arbitrary-admin-task');
$ns = $isAdmin ? 'Admin' : 'NonAdmin';
$controller = app()->make("{$ns}\\IndexController");
return $controller->callAction('index', $parameters = []);
});
});

How to remove missingMethod route when using Route::controller() in Laravel 4?

When I use Route::controller() it will automatically generate a route like: GET|HEAD|POST|PUT|PATCH|DELETE resource/{_missing}.
this will make conflict if I have route like resource/{id}/somethingElse.
Sample code
<?php
Route::controller('page', 'PageController');
Route::Group(['prefix' => 'page/{id}/comments'], function() {
Route::get('/', 'CommentController#index');
Route::post('/', 'CommentController#create'); // <-- this will not work sometimes I don't know why
});
The line I highlighted throws NotFoundHttpException with Controller method not found. message.
Is there anyway to remove that route containing {_missing} parameter?

Resources