Laravel package Controller not found in route - php

I have a simple package and I want to use the controller. When I try to use it in routes I got
Class App\Http\Controllers\Tropicalista\Admin\Controllers\DashboardController
does not exist
I have this in my /routes/web.php
Route::group([
'namespace' => '\Tropicalista\Admin\Controllers',
'prefix'=> 'admin'], function() {
Route::get('/', ['as' => 'admin.root', 'uses' => 'DashboardController#index']);
});
My controller:
namespace Tropicalista\Admin\Controllers;
use Illuminate\Http\Request;
use Analytics;
use Carbon\Carbon;
use Spatie\Analytics\Period;
use Illuminate\Support\Collection;
use Illuminate\Routing\Controller;
class DashboardController extends Controller
{...}
I think is a namespace problem. So how can I call the package controller?

By default, the RouteServiceProvider includes your route files within
a namespace group, allowing you to register controller routes without
specifying the full App\Http\Controllers namespace prefix. So, you
only need to specify the portion of the namespace that comes after the
base App\Http\Controllers namespace.
You need to remove namespace
Route::group(['prefix'=> 'admin'], function() {
Route::get('/', ['as' => 'admin.root', 'uses' => '\Tropicalista\Admin\Controllers\DashboardController#index']);
});

Since it's a package, you need to register the routes in the package.
You can see an example of registering package controllers here:
$routeConfig = [
'namespace' => 'Barryvdh\Debugbar\Controllers',
'prefix' => $this->app['config']->get('debugbar.route_prefix'),
'domain' => $this->app['config']->get('debugbar.route_domain'),
'middleware' => [DebugbarEnabled::class],
];
$this->getRouter()->group($routeConfig, function($router) {
$router->get('open', [
'uses' => 'OpenHandlerController#handle',
'as' => 'debugbar.openhandler',
]);
});

In order to call package controller, change the namespace group of RouteServiceProvider from
protected $namespace = 'App\Http\Controllers';
to null/empty i.e.
protected $namespace = '';
Then, the route can be written as,
Route::get('homepage', 'Package\Namespace\Controllers\ControllerName#ActionName');
Further, if you want to write route for the default controller, use leading slash '/' before starting url.
Route::get('/homepage', 'App\Http\Controllers\ControllerName#ActionName');
Whether it is good practice or not but it solved the problem.

Related

Laravel 7 Auth not working on hosted site

So I am trying to deploy a Laravel site to bluehost however after successful login which should redirect to '/home' and stop. It instead tries to redirect to '/home' then redirects to '/login'. the same code running on localhost with the same database works fine. Other database operations work fine.
Basically the default auth middleware seems to broken somehow.
I used laravel's built in auth to make make the authentication.
here is the live site:
LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
web.php
<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
Route::get('/', 'WelcomeController#index')->name('welcome');
Auth::routes();
// Home
Route::get('/home', 'HomeController#index')->name('home');
//Listings
Route::get('/listings/search', 'ListingController#search')->name('search-listings');
Route::get('/listings/delete/{listing}', 'ListingController#destroy')->name('listing-delete');
Route::resource('listings', 'ListingController');
Route::group(['prefix' => 'messages'], function () {
Route::get('/', ['as' => 'messages', 'uses' => 'MessageController#index']);
Route::get('create', ['as' => 'messages.create', 'uses' => 'MessageController#create']);
Route::post('/', ['as' => 'messages.store', 'uses' => 'MessageController#store']);
Route::get('{id}', ['as' => 'messages.show', 'uses' => 'MessageController#show']);
Route::put('/', ['as' => 'messages.update', 'uses' => 'MessageController#update']);
Route::delete('/', ['as' => 'messages.action', 'uses' => 'MessageController#action']);
});
So it turns out there was a new line before <?php in one of my files in app/config !!
Almost drove me crazy. Worked fine on localhost but not on server. If you encounter this issue, check your .php files for new lines at the beginning of the file.
For me, deleting the files in /bootstrap/cache folder except the .gitignore
then running the command composer dumpautoload worked

Laravel route does not working inside group

I have group of middleware in which I want to add the route but it does not working, the route group is following
Route::group(
[
'domain' => 'admin.'.env('APP_DOMAIN'),
'as' => 'admin.'
],
function () {
Route::group(['namespace' => 'Admin'], function() {
/* I am trying to add route here */
});
})
I need to add following route
Route::post('/dashboard/tokens-sale-record','Admin\DashboardController#totalSaleForChart')->name('tokensSaleRecords');
When I add this route inside above group then it is not working but when I add outside it is working fine. I am using route in ajax.
Can someone kindly let me know what is the issue. I would like to appreciate.
Thank you so much.
Because you already defined Admin\ namespace path in parent group. That's way, You don't use Admin again namespace path in routes in the group.
Can you try following route define.
Route::post('/dashboard/tokens-sale-record','DashboardController#totalSaleForChart')->name('tokensSaleRecords');
If you using again Admin\Dashboard, Laravel searching it DashboardController as the Admin\Admin\DashboardController.
Route::group(
[
'domain' => 'admin.'.env('APP_DOMAIN'),
'as' => 'admin.'
],
function () {
Route::group(['namespace' => 'Admin'], function() {
Route::post('/dashboard/tokens-sale-record','DashboardController#totalSaleForChart')->name('tokensSaleRecords');
});
});
There is no need to write admin before calling controller. It will check for Admin\Admin\DashboardController.
If you are not able to find right route then use php artisan route:list | grep tokens-sale-record to check for the right route.

Defining custom namespaces on routes in laravel 5.6

So Consider the following:
Route::middleware('web')
->namespace('App\Modules\Config\Controllers')
->group(function () {
Route::get('config', ['as' => 'config.index', 'uses' => 'Config#index']);
Route::put('config', ['as' => 'config.update', 'uses' => 'Config#update']);
Route::patch('config', 'Config#update');
});
This explodes when I hit any of these routes because:
Class App\Http\Controllers\App\Modules\Config\Controllers\Config does not exist
Is there not a way in laravel 5.6 to say: No I don't want to use App\Http\Controllers I want to use the namespace I specified?
Try with a slash
->namespace('\App\Modules\Config\Controllers')
If you look at RouteServiceProvider you see that there exists property
protected $namespace = 'App\Http\Controllers';
It's your root namespase and you can change it for example:
protected $namespace = 'App\Modules\Config\Controllers';
or just erase and set namespase directly in your route file for any group.

Difference between middleware route group and namespaces route group in laravel 5.1?

I was reading laravel 5.1 documentation. I didn't understand how laravel route group working and what's the difference between following route groups.
Route Groups & Named Routes
If you are using route groups, you may specify an as keyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group:
Route::group(['as' => 'admin::'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
// Route named "admin::dashboard"
}]);
});
Middleware
To assign middleware to all routes within a group, you may use the middleware key in the group attribute array. Middleware will be executed in the order you define this array:
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Namespaces
Another common use-case for route groups is assigning the same PHP namespace to a group of controllers. You may use the namespace parameter in your group attribute array to specify the namespace for all controllers within the group:
Route::group(['namespace' => 'Admin'], function()
{
// Controllers Within The "App\Http\Controllers\Admin" Namespace
Route::group(['namespace' => 'User'], function()
{
// Controllers Within The "App\Http\Controllers\Admin\User" Namespace
});
});
Sub-Domain Routing
Route groups may also be used to route wildcard sub-domains. 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 using the domain key on the group attribute array:
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Route Prefixes
The prefix group array attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
});
You may also use the prefix parameter to specify common parameters for your grouped routes:
Route::group(['prefix' => 'accounts/{account_id}'], function () {
Route::get('detail', function ($account_id) {
// Matches The accounts/{account_id}/detail URL
});
});
Ref: http://laravel.com/docs/5.1/routing
Route groups allow you to group together routes that share common attributes without having to redefine said attributes for each route.
Example
As an example lets use the namespace array attribute.
Say we have a controller called NewsController that contains all the Admin logic for your apps news section. You may place this file within the 'App/Http/Controllers/Admin` directory.
Laravel 5 follows PSR-4 autoloading conventions, so the application expcets the namespace to be identical to the path of the file, so our class might look something like this:
<?php
namespace App\Http\Controllers\Admin;
class NewsController
{
}
We could write a route to this class like so:
Route::get('admin/news', [
'uses' => 'Admin\NewsController#index'
]);
Note: Laravel automatically assumes all your controllers will be in the App/Http/Controllers directory so we can leave this out of any controller declarations in the routes file.
The above should work fine, but maybe you also have a dozen or so other class files that deal with Admin logic all within the same namespace. We can use the namespace option to group these together.
Route::group(['namespace' => 'Admin'], function()
{
Route::get('admin/news', [
'uses' => 'NewsController#index'
]);
Route::get('admin/users', [
'uses' => 'UserController#index'
]);
...
});
Notice how I no longer define the Admin namespace for the controller for each route.
The same process can be applied to middleware, subdomains, and url prefixes.
Further Example
Lets take the first example and build on it. As you can see from the above route declarations all our admin routes share a common url prefix.
http://example.com/admin/news
http://example.com/admin/users
We can use the prefix array attribute to define the common url for our routes. In our case this is admin.
Our updated Route declarations would look like so.
Route::group(['namespace' => 'Admin', 'prefix' => 'admin'], function()
{
Route::get('news', [
'uses' => 'NewsController#index'
]);
Route::get('users', [
'uses' => 'UserController#index'
]);
...
});
Your probably wondering why would this be useful? Well imagine you have developed a large application with tens if not hundreds of routes. Then one day your boss comes to you and says "Hey Mr. tester, we need to change the admin url from /admin to /cms, how long will this take?".
If you've declared all your routes using groups with the prefix array attribute like above, this is going to be an easy and painless process for you.

Laravel 5 can't find class for custom namespace

In my Laravel app I'm splitting the front end and back end code into folder. These are app/Http/Controllers/BackEnd and app/Http/Controllers/FrontEnd. Rather than type all that out on every file I thought it would be easier to define two namespaces, BackEnd and FrontEnd. I've edited my composer file to this:
"autoload": {
"classmap": [
"app/Models",
"database"
],
"psr-4": {
"App\\": "app/",
"BackEnd\\": "app/Http/Controllers/BackEnd",
"FrontEnd\\": "app/Http/Controllers/FrontEnd"
}
},
I then ran composer autodump and set up my route file like this:
Route::group(['prefix' => 'webman', 'middleware' => 'auth', 'namespace' => 'BackEnd'], function()
{
Route::get('/', ['as' => 'webmanHome', 'uses' => 'HomeController#index']);
});
But when I browse to localhost:8000/webman/ I just get an error, Class App\Http\Controllers\BackEnd\HomeController does not exist. The controller does exist, this is the file:
<?php namespace BackEnd;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class HomeController extends Controller {
/**
* Display the admin home page, showing the front-end menu and "apps" as links to other sections of the ACP.
*
* #param Reqeust $request
*
* #return View
*/
public function index(Request $request)
{
return view('backend.index');
}
}
I've checked vendor/composer/autoload_psr4.php to make sure that the namespace is being defined and it is, this is in the array returned 'BackEnd\\' => array($baseDir . '/app/Http/Controllers/BackEnd'),.
Strangely if I use <?php namespace App\Http\Controllers\BackEnd; at the top of HomeController.php then everything works, why? What am I missing? Why can't autoload find the file with just BackEnd?
When setting namespace in Route::group() it is actually appending that to App\Http\Controllers. What you could do is remove it and reference the full path like so:
Route::group(['prefix' => 'webman', 'middleware' => 'auth'], function()
{
Route::get('/', ['as' => 'webmanHome', 'uses' => '\BackEnd\HomeController#index']);
});
Try changing/commenting the below line in RouteServiceProvider.php
protected $namespace = 'App\Http\Controllers';
There's an interesting and easy way to get around this... Service Providers.
When the route file is loaded via a provider, the 'App\Http...' is not enforced.
public function boot()
{
$this->loadRoutesFrom(app_path('Your/Model/routes.php'));
}
Keep in mind no middleware is attached either. Your route group will have to specify a 'web' middleware or you'll go nuts wondering why validation, etc, isn't working anymore....(been there!)
It's a cool way to go about it anyway, using providers leads to more modular code and re-use.

Categories