Skip to content

Enabling & Disabling Modules ​

Introduction ​

The Modules screen is kitloom's answer to the WordPress Plugins screen. It lists every installed module with its name, description, version and admin packages, and lets an administrator Deactivate and Activate it.

PanelWhere
FilamentModules → Installed Modules, between Appearance and Tools
NovaModules → Installed Modules (/nova/modules)

The screen is guarded by the activate_plugins permission, which only administrators have by default.

Hooking it in ​

Deactivation works by not registering the module's service providers. Packages are not loaded yet at that point, so the site has to hand this over once, in bootstrap/app.php:

php
use Kitloom\Modules\Modules;

$app = Application::configure(basePath: dirname(__DIR__))
    ->withRouting(/* ... */)
    ->withMiddleware(/* ... */)
    ->withExceptions(/* ... */)
    ->create();

Modules::bootstrap($app);

return $app;

Modules::bootstrap() swaps Laravel's package manifest for one that leaves deactivated modules out, right before providers are registered. Both skeletons already contain this line. Without it, the Modules screen shows a notice and deactivation has no effect.

What deactivating does ​

A deactivated module is not loaded at all:

  • its service providers and the providers of its admin packages are not registered;
  • its routes, middleware, page parts, admin sections and permissions disappear;
  • its tables, options and meta stay in the database — activating it brings everything back.

The change takes effect on the next request; the screen reloads itself after a change.

Dependencies ​

Modules depend on each other the way their Composer packages do, and the screen follows the same graph:

  • Deactivating a module also unloads every package that depends on it. That is why a module cannot be deactivated while something other than its own admin packages depends on it — another module, a theme or a core package. The screen names the blockers:

    The Custom Fields module cannot be deactivated: Post Types depend on it.

  • Activating a module is refused while a module it depends on is deactivated:

    The Post Types module needs Custom Fields: activate them first.

  • Core packages — site, wp-schema, settings, modules and the others listed in Overview — are not modules and cannot be deactivated.

  • The roles module (kitloom/permissions) is deliberately not on the screen: switching it off would open the whole admin to everyone. It is installed and removed through Composer only.

Where the state lives ​

The list of deactivated modules is a JSON array in the options table:

OptionExample value
kitloom_inactive_modules["kitloom/link-counter","kitloom/search-replace"]

The name is configurable (kitloom-modules.option). It is intentionally not WordPress's active_plugins — on a live WordPress database that option belongs to WordPress.

Because the list holds deactivated modules, a module deployed tomorrow is active the moment it arrives.

The option is read before the database service exists, so kitloom/modules opens its own short-lived connection from your database config and closes it right after. When the table does not exist yet — a first deploy, package:discover — nothing is considered deactivated.

Programmatic use ​

The same rules are available in code through Kitloom\Modules\ModuleCatalog:

php
use Kitloom\Modules\ModuleCatalog;

$catalog = app(ModuleCatalog::class);

foreach ($catalog->all() as $module) {
    echo $module->name, $module->active ? ' (active)' : '';
}

$catalog->deactivate('kitloom/link-counter'); // throws when something depends on it
$catalog->activate('kitloom/link-counter');   // throws when a dependency is off

A Module carries package, name, description, version, active, admins (its admin packages), blockers and missing.

Caveats ​

  • Long-running processes. With route:cache, Octane or queue workers, a change applies after the cache is rebuilt or the workers restart — the same as any change to the provider list.
  • Direct use from site code. If your own application code imports classes of a module, deactivating the module can break that code. Talk to modules through registries and contracts where you can.