Junior
Junior

Reputation: 11990

How to move my controllers into a separate package folder in Laravel 5.2?

I build a small app using laravel 5.2. I put all of my files into a folder called Surveys located at App/Modules/Surveys. "No worries, I am planning to move the Modules out of the App folder, I just need to get the controller to work"

Currently my controller is located on App/Http/Controllers/SurveysController

I want to move my controller folder so it is located on App/Modules/Surveys/Controllers/Frontend/SurveysController

How would I tell laravel to resolve the controller out of this path App/Modules/Surveys/Controllers/Frontend/ instead of App/Http/Controllers?

I tried to do this into a service provider but it is still not working

<?php

namespace App\Modules\Surveys\Providers;

use Illuminate\Support\ServiceProvider;

class PackageServiceProvider extends ServiceProvider
{

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {

        if (! $this->app->routesAreCached()) {
            require __DIR__.'/../routes.php';
        }

    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

        $this->app->make('Modules\Surveys\Controllers\Frontend\SurveyController');
    }

}

What should I do to make the routes point to the correct controller?

Just for clarity my Application instructor starts at the App

App/Https/Controllers App/Modules/Surveys

Upvotes: 4

Views: 1116

Answers (2)

Junior
Junior

Reputation: 11990

I think I figured it out.

Inside the App/Providers/RouteServiceProvider file, I changed the value of $namespace variable to an empty string like this

Changed the following line protected $namespace = 'App\Http\Controllers';

To this protected $namespace = '';

Then inside my routes.php file I used the namespace like this

Route::group([
    'namespace' => 'Modules\Vendname\Surveys\Controllers\Frontend',
], function()
{
    Route::get('/survey', ['as' =>'survey.index', 'uses' => 'SurveysController@index']);
});

I am not sure why Taylor have the value hard coded in the service provider and not an option in the configs but this solution seems to work!

I would been better if there is a dynamic way to override that value.

Upvotes: 5

Sergio Guillen Mantilla
Sergio Guillen Mantilla

Reputation: 1468

By default controller's namespace is App\Http\Controllers which is defined in RouteServiceProvider and has a property $namespace so all controllers are supposed to be inside the App\Http\Controllers controller.

I think you have more modules and not only Surveys module, you can set the RouteServiceProvider's $namespace property to 'App\Modules' and define your routes as:

Route::get('some/route', ['uses' => 'Surveys\Controllers\Frontend\SurveyController@someMethod']);

If you feel that a huge prefix namespace on each route is ugly you could create a ModuleFooRouteServiceProvider for each module and require a file like 'routesModuleFoo.php' the same way as RouteServiceProvicer does and register those service providers on config/app.php file like:

'providers' => [
    ...
    App\Modules\Surveys\SurveysRouteServiceProvider::class,
    App\Modules\ModuleFoo\ModuleFooRouteServiceProvider::class,
    ...
]

And ModuleFooServiceProvider would look like:

use Illuminate\Routing\Router;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class ModuleFooServiceProvider extends ServiceProvider
{
    protected $namespace = 'App/Modules/ModuleFoo/Controllers';

    public function boot(Router $router)
    {
        parent::boot($router);
    }

    public function map(Router $router)
    {
        $router->group(['namespace' => $this->namespace], function ($router)        {
            require app_path('Http/routesModuleFoo.php');
        });
    }
}

And your routes for that module will be defined on routesModuleFoo.php

Upvotes: 1

Related Questions