N°9618 - Be able to write comment in MyModuleSettings

N°9618 - Be able to write comment in MyModuleSettings
This commit is contained in:
odain
2026-05-19 23:56:21 +02:00
parent b29a3b5df8
commit 2ecd2d7a96
5 changed files with 152 additions and 4 deletions

View File

@@ -20,6 +20,16 @@
*
*/
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
use Combodo\iTop\Setup\ModuleDiscovery\ModuleFileReaderException;
use PhpParser\Comment;
use PhpParser\Error;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use PhpParser\ParserFactory;
define('ITOP_APPLICATION', 'iTop');
define('ITOP_APPLICATION_SHORT', 'iTop');
@@ -2124,6 +2134,29 @@ class Config
eval('?'.'>'.trim($sConfigCode));
$sNoise = trim(ob_get_contents());
ob_end_clean();
try {
$oParser = (new ParserFactory())->createForNewestSupportedVersion();
foreach ($oParser->parse($sConfigCode) as $oNode) {
if ($oNode instanceof \PhpParser\Node\Stmt\Expression) {
/** @var \PhpParser\Node\Stmt\Expression $oNode */
$oExpr = $oNode->expr;
if ($oExpr instanceof Assign) {
/** @var Assign $oExpr */
$oVar = $oExpr->var;
if ($oVar instanceof Variable && $oVar->name === "MyModuleSettings") {
if ($oExpr->expr instanceof Array_) {
$oPhpExpressionEvaluator = new PhpExpressionEvaluator();
$aArrayWithComments = $oPhpExpressionEvaluator->GetArrayWithComments($oExpr->expr);
$MyModuleSettings = array_replace_recursive($aArrayWithComments, $MyModuleSettings);
}
}
}
}
}
} catch (Error $e) {
var_dump($e);
}
} catch (Error $e) {
// PHP 7
throw new ConfigException(
@@ -2714,6 +2747,13 @@ class Config
foreach ($this->m_aModuleSettings as $sModule => $aProperties) {
fwrite($hFile, "\t'$sModule' => array (\n");
foreach ($aProperties as $sProperty => $value) {
if (is_string($value) && false !== strpos($value, 'PhpParserComment')) {
$value = preg_replace(["/.*StartPhpParserComment/", "/EndPhpParserComment/"],
['', ''],
$value);
fwrite($hFile, "\t\t$value\n");
continue;
}
$sNiceExport = self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MyModuleSettings', $sProperty), $value, "\t\t");
fwrite($hFile, "\t\t'$sProperty' => $sNiceExport,\n");
}
@@ -2883,7 +2923,7 @@ class Config
}
/**
* Pretty format a var_export'ed value so that (if possible) the identation is preserved on every line
* Pretty format a var_export'ed value so that (if possible) the indentation is preserved on every line
*
* @param array $aParserValue
* @param mixed $value The value to export
@@ -2900,12 +2940,17 @@ class Config
}
$sExport = var_export($value, true);
if (strpos($sExport, 'PhpParserComment')) {
$sExport = preg_replace(["/.*StartPhpParserComment/", "/EndPhpParserComment',/"],
['', ''],
$sExport);
}
$sNiceExport = str_replace(["\r\n", "\n", "\r"], "\n".$sIndentation, trim($sExport));
if (!$bForceIndentation) {
/** @var array $aImported */
$aImported = null;
eval('$aImported='.$sNiceExport.';');
// Check if adding the identations at the beginning of each line
// Check if adding the indentations at the beginning of each line
// did not modify the values (in case of a string containing a line break)
if ($aImported != $value) {
$sNiceExport = $sExport;
@@ -2914,7 +2959,6 @@ class Config
return $sNiceExport;
}
}
class ConfigPlaceholdersResolver

View File

@@ -260,6 +260,11 @@ class ModuleFileReader
}
$aModuleConfig = $this->oPhpExpressionEvaluator->EvaluateExpression($oModuleConfigInfo->value);
if (isset($aModuleConfig['settings'])) {
$oPhpExpressionEvaluator = new PhpExpressionEvaluator();
$aArrayWithComments = $oPhpExpressionEvaluator->GetArrayWithComments($oModuleConfigInfo->value);
$aModuleConfig['settings'] = array_replace_recursive($aArrayWithComments['settings'], $aModuleConfig['settings']);
}
if (! is_array($aModuleConfig)) {
throw new ModuleFileReaderException("3rd parameter to SetupWebPage::AddModule not an array: ".get_class($oModuleConfigInfo->value), 0, null, $sModuleFilePath);

View File

@@ -4,9 +4,11 @@ namespace Combodo\iTop\PhpParser\Evaluation;
use Combodo\iTop\Setup\ModuleDiscovery\ModuleFileParser;
use Combodo\iTop\Setup\ModuleDiscovery\ModuleFileReaderException;
use PhpParser\Comment;
use PhpParser\ConstExprEvaluator;
use PhpParser\ExprEvaluator;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\ParserFactory;
/**
@@ -55,4 +57,31 @@ PHP;
throw new ModuleFileReaderException("Eval of '$sExpr' caused an error:".$t->getMessage());
}
}
public function GetArrayWithComments(Array_ $oArray): array
{
$aRes = [];
$i=0;
foreach ($oArray->items as $oItem) {
/** @var \PhpParser\Node\ArrayItem $oItem **/
if(is_null($oItem->key)){
$sKey = $i;
$i++;
} else {
$sKey = $this->EvaluateExpression($oItem->key);
}
foreach ($oItem->getComments() as $oComment) {
/** @var \PhpParser\Comment $oComment */
$aRes[] = 'StartPhpParserComment'.$oComment->getText().'EndPhpParserComment';
}
if ($oItem->value instanceof Array_) {
$aRes[$sKey] = $this->GetArrayWithComments($oItem->value);
} elseif ($oItem->value instanceof Comment) {
$aRes[$sKey] = $oItem->value;
} else {
$aRes[$sKey] = $this->EvaluateExpression($oItem->value);
}
}
return $aRes;
}
}

View File

@@ -72,7 +72,6 @@ class ConfigTest extends ItopTestCase
'sExpectedContains' => "'app_root_url' => 'http://%server(SERVER_NAME)?:localhost%/itop/iTop/'",
'aChanges' => [],
],
'preserve set same value' => [
'sConfigFile' => __DIR__.'/ConfigTest/config-itop-var.php',
'sExpectedContains' => "'app_root_url' => 'http://' . (isset(\$_SERVER['SERVER_NAME']) ? \$_SERVER['SERVER_NAME'] : 'localhost') . '/itop/iTop/'",
@@ -91,4 +90,21 @@ class ConfigTest extends ItopTestCase
],
];
}
public function testPreserveModuleSettingsOnWriteToFile()
{
$sTmpFile = tempnam(sys_get_temp_dir(), "target");
$sConfigFile = __DIR__.'/ConfigTest/config-itop-modulesetting.php';
$oConfig = new Config($sConfigFile);
$oConfig->WriteToFile($sTmpFile);
$this->assertFileExists($sTmpFile);
$this->assertEquals($this->GetModuleSettingSection($sConfigFile), $this->GetModuleSettingSection($sTmpFile));
}
private function GetModuleSettingSection(string $sFilePath) : string {
preg_match('/\$MyModuleSettings[\w\W]*\/\*\*/m', file_get_contents($sFilePath), $aMatches);
return preg_replace(['/[ ]+/', '/[ ]+/'],[' ', ' '], $aMatches[0]);
}
}

View File

@@ -0,0 +1,54 @@
<?php
/**
*
* Configuration file, generated for the unit tests
*
*
*
*/
$MySettings = [
];
/**
*
* Modules specific settings
*
*/
$MyModuleSettings = array(
'combodo-hybridauth' => array (
//debug to add traces...
'debug' => false,
'providers' => array (
'Keycloak' =>
/*
ga
bu
zo meu
*/
array (
'keys' =>
array (
/**
* sha
*
* dok
*/
'id' => 'my-clientid',
'secret' => 'my-secret',
),
'enabled' => false,
),
//url to access IdP
'url' => 'keycloak_url',
),
),
);
/**
*
* Data model modules to be loaded. Names are specified as relative paths
*
*/
$MyModules = [
];