app->register(RouteServiceProvider::class); $this->mergeConfigFrom( module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower(), ); } /** * Bootstrap module services. */ public function boot(): void { $this->registerTranslations(); $this->registerConfig(); $this->registerViews(); $this->registerHelpers(); $this->registerCommands(); $this->registerLivewireComponents(); $this->registerPolicies(); $this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations')); } /** * Register Livewire components used by the module. */ protected function registerLivewireComponents(): void { Livewire::component('helpdesk.ticket-index', TicketIndex::class); Livewire::component('helpdesk.ticket-create', TicketCreate::class); Livewire::component('helpdesk.ticket-show', TicketShow::class); Livewire::component('helpdesk.ticket-timer', TicketTimer::class); Livewire::component('helpdesk.dashboard-widget', HelpdeskDashboardWidget::class); Livewire::component('helpdesk.kanban-board', KanbanBoard::class); Livewire::component('helpdesk.settings-manager', SettingsManager::class); } /** * Register policies and gates. */ protected function registerPolicies(): void { Gate::policy(Ticket::class, TicketPolicy::class); Gate::define('helpdesk-admin', static fn ($user): bool => method_exists($user, 'isAdmin') && $user->isAdmin()); Gate::define('helpdesk-agent', static fn ($user): bool => (method_exists($user, 'isAdmin') && $user->isAdmin()) || (bool) ($user->helpdesk_agent ?? false)); } /** * Register helpers. */ protected function registerHelpers(): void { foreach (glob(module_path(ModuleInfo::name(), 'Helpers/*.php')) ?: [] as $filename) { require_once $filename; } } /** * Dynamically register console commands. */ protected function registerCommands(): void { if (! $this->app->runningInConsole()) { return; } $commandPath = module_path(ModuleInfo::name(), 'Console'); if (! is_dir($commandPath)) { return; } $commands = collect(File::allFiles($commandPath)) ->map(fn ($file): string => 'Modules\\'.$this->moduleName.'\\Console\\'.$file->getFilenameWithoutExtension()) ->filter(fn (string $class): bool => class_exists($class)) ->values() ->all(); $this->commands($commands); } /** * Register config publishing. */ protected function registerConfig(): void { $this->publishes([ module_path(ModuleInfo::name(), 'Config/config.php') => config_path(ModuleInfo::nameLower().'.php'), ], 'config'); } /** * Register module views. */ protected function registerViews(): void { $sourcePath = module_path(ModuleInfo::name(), 'Resources/views'); $themeRoot = rtrim((string) config('stylist.themes_path', resource_path('themes')), DIRECTORY_SEPARATOR); $backendTheme = (string) config('stylist.default_backend_theme', 'backend'); $viewPath = $themeRoot.DIRECTORY_SEPARATOR.$backendTheme .DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'modules'.DIRECTORY_SEPARATOR.ModuleInfo::nameLower(); // Module source views remain module-owned. Any application override is // published into the selected backend theme, never resources/views. $this->publishes([ $sourcePath => $viewPath, ], ['views', ModuleInfo::nameLower().'-module-views']); $this->loadViewsFrom($sourcePath, ModuleInfo::nameLower()); Blade::componentNamespace('Modules\Helpdesk\View\Components', 'helpdesk'); Blade::anonymousComponentPath($sourcePath.'/components', 'helpdesk'); } /** * Register translations. */ protected function registerTranslations(): void { $langPath = resource_path('lang/modules/'.ModuleInfo::nameLower()); if (is_dir($langPath)) { $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower()); return; } $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower()); } /** * Get provided services. * * @return array */ public function provides(): array { return []; } }