instance = $instance; $this->entry = $entry; } // ===== Serialization ===== public function jsonSerialize(): array { return [ 'id' => $this->id(), 'handle' => $this->handle(), 'version' => $this->version(), 'namespace' => $this->namespace(), 'installed' => $this->installed(), 'enabled' => $this->enabled(), 'needsUpgrade' => $this->needsUpgrade(), ]; } // ===== State from ModuleEntry (database) ===== public function id(): ?string { return $this->entry?->getId(); } public function installed(): bool { return $this->entry?->getInstalled() ?? false; } public function enabled(): bool { return $this->entry?->getEnabled() ?? false; } // ===== Information from ModuleInterface (filesystem) ===== public function handle(): string { if ($this->instance) { return $this->instance->handle(); } if ($this->entry) { return $this->entry->getHandle(); } throw new \RuntimeException('Module has neither instance nor entry'); } public function namespace(): ?string { if ($this->entry) { return $this->entry->getNamespace(); } if ($this->instance) { // Extract namespace from class name $className = get_class($this->instance); $parts = explode('\\', $className); if (count($parts) >= 2 && $parts[0] === 'KTXM') { return $parts[1]; } } return null; } public function version(): string { // Prefer current version from filesystem if ($this->instance) { return $this->instance->version(); } // Fallback to stored version if ($this->entry) { return $this->entry->getVersion(); } return '0.0.0'; } public function permissions(): array { return $this->instance?->permissions() ?? []; } // ===== Computed properties ===== public function needsUpgrade(): bool { if (!$this->instance || !$this->entry || !$this->installed()) { return false; } $currentVersion = $this->instance->version(); $storedVersion = $this->entry->getVersion(); return version_compare($currentVersion, $storedVersion, '>'); } // ===== Access to underlying objects ===== public function instance(): ?ModuleInstanceInterface { return $this->instance; } public function entry(): ?ModuleEntry { return $this->entry; } // ===== Lifecycle methods (delegate to instance) ===== public function boot(): void { $this->instance?->boot(); } public function install(): void { $this->instance?->install(); } public function uninstall(): void { $this->instance?->uninstall(); } public function enable(): void { $this->instance?->enable(); } public function disable(): void { $this->instance?->disable(); } public function upgrade(): void { $this->instance?->upgrade(); } public function registerBI(): array | null { if ($this->instance instanceof ModuleBrowserInterface) { return $this->instance->registerBI(); } return null; } public function registerCI(): array | null { if ($this->instance instanceof ModuleConsoleInterface) { return $this->instance->registerCI(); } return null; } }