Skip to Content
ModulesProvider API

Module Provider API

The Flute CMS Module API provides an interface for managing the module lifecycle via ModuleManager and ModuleServiceProvider.

ModuleManager

ModuleManager is the central class for managing modules. It is automatically initialized upon first access: collects module.json, synchronizes statuses with DB, sorts providers, and checks dependencies.

Getting Instance

<?php use Flute\Core\ModulesManager\ModuleManager; // Via DI container $moduleManager = app(ModuleManager::class); // Via helper $moduleManager = modules();

Main Methods

<?php // Get all modules (including disabled) $allModules = $moduleManager->getModules(); // Get only active modules $activeModules = $moduleManager->getActive(); // Get specific module $module = $moduleManager->getModule('News'); // Check if module exists $exists = $moduleManager->issetModule('Shop'); // Get module JSON data $moduleJson = $moduleManager->getModuleJson('BansManager'); // Clear module cache $moduleManager->clearCache(); // Refresh module list $moduleManager->refreshModules(); // Module boot times (for profiling) $bootTimes = $moduleManager->getModulesBootTimes();

ModuleInformation

Each module is represented by a ModuleInformation object with the following properties:

<?php $module = $moduleManager->getModule('News'); // Available properties $module->key; // Module key: 'News' $module->name; // Name: 'News' $module->description; // Module description $module->version; // Version: '1.0.0' $module->status; // Status: 'active', 'disabled', 'notinstalled' $module->createdAt; // Installation date $module->dependencies; // Array of dependencies $module->providers; // Array of providers

Module Statuses

StatusConstantDescription
ActiveModuleManager::ACTIVEModule is installed and working
DisabledModuleManager::DISABLEDModule is installed but disabled
Not InstalledModuleManager::NOTINSTALLEDModule is not installed

Checking Status

<?php class ModuleInfoService { protected ModuleManager $moduleManager; public function __construct(ModuleManager $moduleManager) { $this->moduleManager = $moduleManager; } /** * Check if module is active */ public function isModuleActive(string $moduleName): bool { $activeModules = $this->moduleManager->getActive(); return $activeModules->has($moduleName); } /** * Get module status */ public function getModuleStatus(string $moduleName): string { if (!$this->moduleManager->issetModule($moduleName)) { return ModuleManager::NOTINSTALLED; } $module = $this->moduleManager->getModule($moduleName); return $module->status; } /** * Get module information */ public function getModuleInfo(string $moduleName): ?ModuleInformation { try { return $this->moduleManager->getModule($moduleName); } catch (\Exception $e) { return null; } } }

Working with Dependencies

<?php use Flute\Core\ModulesManager\ModuleDependencies; $dependencyChecker = $moduleManager->getModuleDependencies(); $module = $moduleManager->getModule('Shop'); $activeModules = $moduleManager->getActive(); $themeInfo = app(\Flute\Core\Theme\ThemeManager::class)->getThemeInfo(); try { // Check all module dependencies $dependencyChecker->checkDependencies( $module->dependencies, $activeModules, $themeInfo ); echo "All dependencies satisfied"; } catch (\Flute\Core\ModulesManager\Exceptions\ModuleDependencyException $e) { echo "Dependency error: " . $e->getMessage(); }

In the normal boot cycle, ModuleManager automatically checks dependencies and disables problematic modules.

Composer Integration

<?php // Run composer install for specific module // (if app/Modules/<Module>/composer.json exists) $moduleManager->runComposerInstall($module); // Force install for the entire project $moduleManager->runComposerInstall(null, true);

ModuleServiceProvider

ModuleServiceProvider is the base class for all module providers. It provides methods for loading module resources.

Basic Provider Structure

<?php namespace Flute\Modules\News\Providers; use Flute\Core\Support\ModuleServiceProvider; class NewsProvider extends ModuleServiceProvider { /** * List of extensions (optional) */ public array $extensions = []; /** * Register services in DI container * Called first, before boot() */ public function register(\DI\Container $container): void { // Register services $container->set(NewsService::class, \DI\autowire()); } /** * Load module resources * Called after register() */ public function boot(\DI\Container $container): void { // Automatically load all resources $this->bootstrapModule(); // Load views $this->loadViews('Resources/views', 'news'); // Load styles $this->loadScss('Resources/assets/scss/news.scss'); // Conditionally load admin package if (is_admin_path() && user()->can('admin')) { $this->loadPackage(new NewsAdminPackage()); } } }

Resource Loading Methods

bootstrapModule()

Automatically loads all standard module resources:

<?php $this->bootstrapModule(); // Equivalent to calling: // $this->loadEntities(); - DB entities // $this->loadConfigs(); - configuration // $this->loadTranslations(); - translations // $this->loadRouterAttributes();- routes from attributes // $this->loadComponents(); - components // $this->loadWidgets(); - widgets

bootstrapModule() caches results for defaultCacheDuration to optimize performance.

Loading Individual Resources

<?php // Load database entities from database/Entities $this->loadEntities(); // Load configuration from Resources/config $this->loadConfigs(); // Load translations from Resources/lang $this->loadTranslations(); // Load routes via attributes from Http/Controllers $this->loadRouterAttributes(); // Load components from Components/ $this->loadComponents(); // Load widgets from Widgets/ $this->loadWidgets();

Views and Styles

<?php // Load views // First argument — path relative to module // Second — namespace for use in view() $this->loadViews('Resources/views', 'news'); // Now you can use: // view('news::articles.index') // view('news::partials.sidebar') // Load SCSS files $this->loadScss('Resources/assets/scss/style.scss'); // Load SCSS for admin panel if (is_admin_path()) { template()->getTemplateAssets()->addScssFile( $this->getModulePath('Resources/assets/scss/admin.scss'), 'admin' ); }

Components

<?php // Load one component $this->loadComponent(NewsCardComponent::class, 'news-card'); // Register multiple components $this->registerComponents([ 'news-card' => NewsCardComponent::class, 'news-list' => NewsListComponent::class, 'news-featured' => NewsFeaturedComponent::class, ]);

Admin Packages

<?php // Load admin package $this->loadPackage(new NewsAdminPackage()); // Conditional load only for admin panel if (is_admin_path()) { $this->loadPackage(new NewsAdminPackage()); }

Routes

<?php // Load routes.php manually (not called automatically) $this->loadRoutes(); // File must be: Resources/routes/routes.php

Getting Paths

<?php // Get absolute path to module file $configPath = $this->getModulePath('Resources/config/settings.php'); // Result: /var/www/app/Modules/News/Resources/config/settings.php

Practical Examples

<?php namespace Flute\Modules\Shop\Providers; use Flute\Core\Support\ModuleServiceProvider; use Flute\Modules\Shop\Services\ProductService; use Flute\Modules\Shop\Services\CartService; use Flute\Modules\Shop\Admin\Package\ShopPackage; class ShopProvider extends ModuleServiceProvider { public function register(\DI\Container $container): void { // Register services $container->set(ProductService::class, \DI\autowire()); $container->set(CartService::class, \DI\autowire()); // Register interfaces $container->set(ProductServiceInterface::class, \DI\get(ProductService::class)); } public function boot(\DI\Container $container): void { // Basic load $this->bootstrapModule(); // Views and styles $this->loadViews('Resources/views', 'shop'); $this->loadScss('Resources/assets/scss/shop.scss'); // External libraries template()->addStyle(url('assets/css/libs/swiper.min.css')); template()->addScript(url('assets/js/libs/swiper.js')); // Components $this->registerComponents([ 'product-card' => ProductCardComponent::class, 'cart-widget' => CartWidgetComponent::class, ]); // Event listeners events()->addListener( UserRegisteredEvent::NAME, [UserRegistrationListener::class, 'handle'] ); // Admin package if (is_admin_path()) { $this->loadPackage(new ShopPackage()); } } }

Provider with Conditional Loading

<?php namespace Flute\Modules\BansManager\Providers; use Flute\Core\Support\ModuleServiceProvider; class BansManagerProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { // Base resources loaded always $this->loadEntities(); $this->loadConfigs(); $this->loadTranslations(); // Main service $container->set(BansManager::class, \DI\autowire()); // Frontend resources only for frontend if (!is_admin_path()) { $this->loadViews('Resources/views', 'bans-manager'); $this->loadScss('Resources/assets/scss/main.scss'); $this->loadRouterAttributes(); // Components for frontend $this->registerComponents([ 'bans-table' => BansTableComponent::class, 'mutes-table' => MutesTableComponent::class, ]); } // Admin resources only for admin panel if (is_admin_path()) { $this->loadPackage(new BansManagerPackage()); template()->getTemplateAssets()->addScssFile( $this->getModulePath('Resources/assets/scss/admin.scss'), 'admin' ); } // Register drivers $bansManager = $container->get(BansManager::class); $bansManager->registerDriver('SourceBans', SourceBansDriver::class); } }

Error Handling

<?php public function boot(\DI\Container $container): void { try { $this->bootstrapModule(); $this->loadCustomResources(); } catch (\Exception $e) { // Log error logs('modules')->error("Error loading module: " . $e->getMessage()); // In debug mode throw exception if (is_debug()) { throw $e; } // In production continue working without this module } }

Best Practices

Separate register() and boot()

  • register() — only register services in DI container
  • boot() — load resources, register listeners

Use Conditional Loading

Load resources only when needed:

if (is_admin_path()) { $this->loadPackage(new AdminPackage()); }

Follow Loading Order

  1. Configuration
  2. DB Entities
  3. Translations
  4. Routes
  5. Components and widgets
  6. Event listeners

Cache Heavy Operations

bootstrapModule() automatically caches directory scanning results.

Log Errors

Always log initialization errors for easier debugging.

Working with DI Container

Registering Services

<?php public function register(\DI\Container $container): void { // Simple registration with autowiring $container->set(MyService::class, \DI\autowire()); // Interface registration $container->set(MyServiceInterface::class, \DI\get(MyService::class)); // Registration with alias $container->set('my_service', \DI\get(MyService::class)); // Registration with factory $container->set(MyService::class, function() { return new MyService(config('my_module.setting')); }); }

Getting Services

<?php // Via DI container $service = app(MyService::class); // Via alias $service = app('my_service'); // In constructor (autowiring) public function __construct(MyService $service) { $this->service = $service; }