Modules in Laravel

I had to include some pluggable component in my latest Laravel application, a (variable) set of functions acting as "drivers" to fetch and parse contents from different sources. As always I browsed Packagist looking for a package providing this functionality, but I only found module managers intended to extend the application with full MVC modules each providing their own routing resolution, controllers, views... Not exactly what I wanted.

In the end, I've solved the issue with a dummy Service Provider scanning a given folder and registering what is found there. Here the class:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class DriversProvider extends ServiceProvider
{
        public function boot()
        {
                $path = app_path() . '/Drivers/';
                $base_namespace = '\App\Drivers\\';
                $names = array_diff(scandir($path), ['..', '.']);
                foreach($names as $module) {
                        // this is to remove the ".php" part of the filename
                        $module = substr($module, 0, strrpos($module, '.'));
                        $namespace = $base_namespace . $module;
                        $this->app->register($namespace);
                }
        }

        public function register()
        {
        }
}

In each file parked in the app/Drivers folder, I've implemented a Service Providers registering for an Event. Something like:

<?php

namespace App\Drivers;

use Illuminate\Support\ServiceProvider;

use Event;

class MyModule extends ServiceProvider
{
        public function boot()
        {
                Event::subscribe($this);
        }

        public function register()
        {
        }

        public function subscribe($events)
        {
                $events->listen('App\Events\MyEvent', function ($event)
                {
                        // DO IT
                });
        }
}

This approach also has the useful side effect to permit every single module to register for different events, or, to say it different, to have different kind of modules (which was one of my requirements).

Not that elegant, but it works.