<?php
 namespace App\Traits; use App\Core\Module\ManageableModuleManager; use App\Models\Module; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\View\View; trait ManagesModules { abstract protected function moduleType(): string; abstract protected function manager(): ManageableModuleManager; abstract protected function permission(): string; abstract protected function indexView(): string; abstract protected function editView(): string; public function index(): View { $this->authorize($this->permission()); return view($this->indexView(), [ 'type' => $this->moduleType(), 'modules' => Module::ofType($this->moduleType()) ->orderBy('sort_order') ->orderBy('label') ->get(), ]); } public function edit(Module $module): View { $this->authorize($this->permission()); abort_unless($module->type === $this->moduleType(), 404); $fields = $this->manager()->getConfigFields($module->name); return view($this->editView(), [ 'module' => $module->load('settings'), 'fields' => $fields, 'config' => $module->config, ]); } public function update(Request $request, Module $module): RedirectResponse { $this->authorize($this->permission()); abort_unless($module->type === $this->moduleType(), 404); $fields = $this->manager()->getConfigFields($module->name); $rules = collect($fields) ->mapWithKeys(fn (array $f) => [ $f['key'] => $f['rules'] ?? 'nullable|string|max:1024', ]) ->all(); $data = $request->validate($rules); foreach ($fields as $field) { if (($field['type'] ?? null) === 'boolean') { $data[$field['key']] = $request->boolean($field['key']) ? '1' : '0'; } } $encryptedKeys = collect($fields) ->filter(fn (array $f) => ($f['encrypted'] ?? false) === true) ->pluck('key') ->all(); DB::transaction(function () use ($module, $data, $encryptedKeys) { $module->setConfig($data, $encryptedKeys); if (method_exists($this, 'logUpdated')) { $this->logUpdated( model: $module, description: "Updated {$module->type} module {$module->name}" ); } }); return redirect() ->back() ->with('success', __('admin/modules.updated')); } public function toggle(Module $module): JsonResponse { $this->authorize($this->permission()); abort_unless($module->type === $this->moduleType(), 404); $module->update(['enabled' => ! $module->enabled]); if (method_exists($this, 'logUpdated')) { $this->logUpdated( model: $module, description: "Toggled {$module->type} module {$module->name} to " . ($module->enabled ? 'enabled' : 'disabled') ); } return response()->json([ 'enabled' => $module->enabled, 'message' => $module->enabled ? __('admin/modules.toggle_enabled') : __('admin/modules.toggle_disabled'), ]); } public function test(Module $module): JsonResponse { $this->authorize($this->permission()); abort_unless($module->type === $this->moduleType(), 404); $result = $this->manager()->test($module->name, $module->config); $module->markTested($result->success, $result->message); return response()->json([ 'success' => $result->success, 'message' => $result->message, 'context' => $result->context, 'tested_at' => $module->fresh()->last_test_at?->toIso8601String(), ]); } } 