From b012a5c587b4ef97b93e531495016c684c748b8b Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 16 Feb 2026 00:00:00 +0000 Subject: [PATCH] Detected configurable modules when ini key is absent. --- application/src/Module/Module.php | 43 ++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/application/src/Module/Module.php b/application/src/Module/Module.php index 3a4263f29e..a4f381bf5e 100644 --- a/application/src/Module/Module.php +++ b/application/src/Module/Module.php @@ -132,13 +132,48 @@ public function getModuleFilePath() } /** - * Check whether this module is configurable + * Check whether this module is configurable. * - * @return bool + * When the key "configurable" is set in module.ini, its value is used. + * Otherwise, auto-detection checks the form ConfigForm or the content of + * method getConfigForm() via reflection. */ - public function isConfigurable() + public function isConfigurable(): bool { - return (bool) $this->getIni('configurable'); + $configurable = $this->getIni('configurable'); + if ($configurable !== null) { + return (bool) $configurable; + } + + $moduleFilePath = $this->getModuleFilePath(); + if (!$moduleFilePath) { + return false; + } + + // Check ConfigForm. + $moduleDir = dirname($moduleFilePath); + if (file_exists($moduleDir . '/src/Form/ConfigForm.php')) { + return true; + } + + // Check method in module via Reflection. + $moduleClass = $this->getId() . '\Module'; + if (class_exists($moduleClass, false)) { + try { + $ref = new \ReflectionMethod($moduleClass, 'getConfigForm'); + return $ref->getFileName() === realpath($moduleFilePath); + } catch (\ReflectionException $e) { + return false; + } + } + + // Check method in module via file when not active. + if (file_exists($moduleFilePath)) { + $source = file_get_contents($moduleFilePath); + return (bool) preg_match('/function\s+getConfigForm\s*\(/', $source); + } + + return false; } /**