mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-28 21:18:46 +02:00
Compare commits
23 Commits
feature/75
...
feature/47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9872702f59 | ||
|
|
7e7b5874a6 | ||
|
|
11f142b782 | ||
|
|
af790269f0 | ||
|
|
86fe9d6a2b | ||
|
|
cdbe331c35 | ||
|
|
c14ac90a13 | ||
|
|
794a9afe3e | ||
|
|
a0a86782c7 | ||
|
|
ac2b787e09 | ||
|
|
1962cd7a88 | ||
|
|
f7b5091b39 | ||
|
|
a587bd68eb | ||
|
|
08c77f8106 | ||
|
|
61c2b71f1f | ||
|
|
f47309f535 | ||
|
|
79e1572c9e | ||
|
|
812e24b402 | ||
|
|
8af748bd3e | ||
|
|
788b23a485 | ||
|
|
6d80b2e5ed | ||
|
|
07d7995a51 | ||
|
|
1bc14f97e1 |
@@ -2856,20 +2856,8 @@ class Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($aModuleInfo['installer']))
|
|
||||||
{
|
RunTimeEnvironment::CallInstallerHandler($aModuleInfo, "BeforeWritingConfig", [$this]);
|
||||||
$sModuleInstallerClass = $aModuleInfo['installer'];
|
|
||||||
if (!class_exists($sModuleInstallerClass))
|
|
||||||
{
|
|
||||||
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not a PHP class - Module: ".$aModuleInfo['label']);
|
|
||||||
}
|
|
||||||
if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI'))
|
|
||||||
{
|
|
||||||
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not derived from 'ModuleInstallerAPI' - Module: ".$aModuleInfo['label']);
|
|
||||||
}
|
|
||||||
$aCallSpec = array($sModuleInstallerClass, 'BeforeWritingConfig');
|
|
||||||
call_user_func_array($aCallSpec, array($this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->SetAddOns($aAddOns);
|
$this->SetAddOns($aAddOns);
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ if (PHP_VERSION_ID < 50600) {
|
|||||||
echo $err;
|
echo $err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException($err);
|
trigger_error(
|
||||||
|
$err,
|
||||||
|
E_USER_ERROR
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|||||||
@@ -469,6 +469,44 @@ return array(
|
|||||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => $baseDir . '/sources/Form/Validator/SelectObjectValidator.php',
|
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => $baseDir . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||||
'Combodo\\iTop\\Kernel' => $baseDir . '/sources/Kernel.php',
|
'Combodo\\iTop\\Kernel' => $baseDir . '/sources/Kernel.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\AbstractExprEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/AbstractExprEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ArrayDimFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ArrayDimFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ArrayEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ArrayEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BinaryOpEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BinaryOpEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseAndEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BitwiseAndEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseNotEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BitwiseNotEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseOrEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BitwiseOrEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseXorEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BitwiseXorEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanAndEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BooleanAndEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanNotEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BooleanNotEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanOrEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/BooleanOrEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\CastEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/CastEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ClassConstFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ClassConstFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\CoalesceEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/CoalesceEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ConcatEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ConcatEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ConstFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ConstFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\EqualEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/EqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\FuncCallEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/FuncCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\GreaterEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/GreaterEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\GreaterOrEqualEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/GreaterOrEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\IssetEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/IssetEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\MethodCallEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/MethodCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ModEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/ModEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\MulEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/MulEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NotEqualEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/NotEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NullsafeMethodCallEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/NullsafeMethodCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NullsafePropertyFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/NullsafePropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\PropertyFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\SmallerEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/SmallerEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\SmallerOrEqualEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/SmallerOrEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\StaticCallEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/StaticCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\StaticPropertyFetchEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/StaticPropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\TernaryEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/TernaryEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\UnaryMinusEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/UnaryMinusEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\UnaryPlusEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/UnaryPlusEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\VariableEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/VariableEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\iExprEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/iExprEvaluator.php',
|
||||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php',
|
'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php',
|
||||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => $baseDir . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => $baseDir . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
||||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ return array(
|
|||||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||||
'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'),
|
'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'),
|
||||||
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-google/src', $vendorDir . '/league/oauth2-client/src'),
|
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src', $vendorDir . '/league/oauth2-google/src'),
|
||||||
'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'),
|
'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'),
|
||||||
'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'),
|
'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'),
|
||||||
'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'),
|
'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'),
|
||||||
|
|||||||
@@ -317,8 +317,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
),
|
),
|
||||||
'League\\OAuth2\\Client\\' =>
|
'League\\OAuth2\\Client\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
0 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
||||||
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
1 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
||||||
),
|
),
|
||||||
'Laminas\\Validator\\' =>
|
'Laminas\\Validator\\' =>
|
||||||
array (
|
array (
|
||||||
@@ -847,6 +847,44 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/SelectObjectValidator.php',
|
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||||
'Combodo\\iTop\\Kernel' => __DIR__ . '/../..' . '/sources/Kernel.php',
|
'Combodo\\iTop\\Kernel' => __DIR__ . '/../..' . '/sources/Kernel.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\AbstractExprEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/AbstractExprEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ArrayDimFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ArrayDimFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ArrayEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ArrayEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BinaryOpEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BinaryOpEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseAndEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BitwiseAndEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseNotEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BitwiseNotEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseOrEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BitwiseOrEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BitwiseXorEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BitwiseXorEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanAndEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BooleanAndEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanNotEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BooleanNotEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\BooleanOrEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/BooleanOrEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\CastEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/CastEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ClassConstFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ClassConstFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\CoalesceEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/CoalesceEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ConcatEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ConcatEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ConstFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ConstFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\EqualEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/EqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\FuncCallEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/FuncCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\GreaterEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/GreaterEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\GreaterOrEqualEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/GreaterOrEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\IssetEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/IssetEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\MethodCallEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/MethodCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\ModEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/ModEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\MulEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/MulEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NotEqualEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/NotEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NullsafeMethodCallEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/NullsafeMethodCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\NullsafePropertyFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/NullsafePropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\PropertyFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\SmallerEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/SmallerEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\SmallerOrEqualEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/SmallerOrEqualEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\StaticCallEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/StaticCallEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\StaticPropertyFetchEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/StaticPropertyFetchEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\TernaryEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/TernaryEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\UnaryMinusEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/UnaryMinusEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\UnaryPlusEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/UnaryPlusEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\VariableEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/VariableEvaluator.php',
|
||||||
|
'Combodo\\iTop\\PhpParser\\Evaluation\\iExprEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/iExprEvaluator.php',
|
||||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php',
|
'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php',
|
||||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
||||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ if ($issues) {
|
|||||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new \RuntimeException(
|
trigger_error(
|
||||||
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||||
|
E_USER_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,7 +303,11 @@ class iTopExtensionsMap
|
|||||||
else if (preg_match('/^module\.(.*).php$/i', $sFile, $aMatches))
|
else if (preg_match('/^module\.(.*).php$/i', $sFile, $aMatches))
|
||||||
{
|
{
|
||||||
// Found a module
|
// Found a module
|
||||||
$aModuleInfo = $this->GetModuleInfo($sSearchDir.'/'.$sFile);
|
try {
|
||||||
|
$aModuleInfo = ModuleFileReader::GetInstance()->ReadModuleFileInformation($sSearchDir.'/'.$sFile);
|
||||||
|
} catch(ModuleFileReaderException $e){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// If we are not already inside a formal extension, then the module itself is considered
|
// If we are not already inside a formal extension, then the module itself is considered
|
||||||
// as an extension, otherwise, the module is just added to the list of modules belonging
|
// as an extension, otherwise, the module is just added to the list of modules belonging
|
||||||
// to this extension
|
// to this extension
|
||||||
@@ -417,60 +421,6 @@ class iTopExtensionsMap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the information from a module file (module.xxx.php)
|
|
||||||
* Closely inspired (almost copied/pasted !!) from ModuleDiscovery::ListModuleFiles
|
|
||||||
* @param string $sModuleFile
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function GetModuleInfo($sModuleFile)
|
|
||||||
{
|
|
||||||
static $iDummyClassIndex = 0;
|
|
||||||
|
|
||||||
$aModuleInfo = array(); // will be filled by the "eval" line below...
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$aMatches = array();
|
|
||||||
$sModuleFileContents = file_get_contents($sModuleFile);
|
|
||||||
$sModuleFileContents = str_replace(array('<?php', '?>'), '', $sModuleFileContents);
|
|
||||||
$sModuleFileContents = str_replace('__FILE__', "'".addslashes($sModuleFile)."'", $sModuleFileContents);
|
|
||||||
preg_match_all('/class ([A-Za-z0-9_]+) extends ([A-Za-z0-9_]+)/', $sModuleFileContents, $aMatches);
|
|
||||||
//print_r($aMatches);
|
|
||||||
$idx = 0;
|
|
||||||
foreach($aMatches[1] as $sClassName)
|
|
||||||
{
|
|
||||||
if (class_exists($sClassName))
|
|
||||||
{
|
|
||||||
// rename any class declaration inside the code to prevent a "duplicate class" declaration
|
|
||||||
// and change its parent class as well so that nobody will find it and try to execute it
|
|
||||||
// Note: don't use the same naming scheme as ModuleDiscovery otherwise you 'll have the duplicate class error again !!
|
|
||||||
$sModuleFileContents = str_replace($sClassName.' extends '.$aMatches[2][$idx], $sClassName.'_Ext_'.($iDummyClassIndex++).' extends DummyHandler', $sModuleFileContents);
|
|
||||||
}
|
|
||||||
$idx++;
|
|
||||||
}
|
|
||||||
// Replace the main function call by an assignment to a variable, as an array...
|
|
||||||
$sModuleFileContents = str_replace(array('SetupWebPage::AddModule', 'ModuleDiscovery::AddModule'), '$aModuleInfo = array', $sModuleFileContents);
|
|
||||||
|
|
||||||
eval($sModuleFileContents); // Assigns $aModuleInfo
|
|
||||||
|
|
||||||
if (count($aModuleInfo) === 0)
|
|
||||||
{
|
|
||||||
SetupLog::Warning("Eval of $sModuleFile did not return the expected information...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(ParseError $e)
|
|
||||||
{
|
|
||||||
// Continue...
|
|
||||||
SetupLog::Warning("Eval of $sModuleFile caused a parse error: ".$e->getMessage()." at line ".$e->getLine());
|
|
||||||
}
|
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
// Continue...
|
|
||||||
SetupLog::Warning("Eval of $sModuleFile caused an exception: ".$e->getMessage());
|
|
||||||
}
|
|
||||||
return $aModuleInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all available extensions
|
* Get all available extensions
|
||||||
* @return iTopExtension[]
|
* @return iTopExtension[]
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
|
||||||
|
require_once(APPROOT.'setup/modulediscovery/ModuleFileReader.php');
|
||||||
|
|
||||||
class MissingDependencyException extends CoreException
|
class MissingDependencyException extends CoreException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -105,6 +109,9 @@ class ModuleDiscovery
|
|||||||
*/
|
*/
|
||||||
public static function AddModule($sFilePath, $sId, $aArgs)
|
public static function AddModule($sFilePath, $sId, $aArgs)
|
||||||
{
|
{
|
||||||
|
if (is_null($aArgs)||! is_array($aArgs)){
|
||||||
|
throw new ModuleFileReaderException("Error parsing module file args", 0, null, $sFilePath);
|
||||||
|
}
|
||||||
if (!array_key_exists('itop_version', $aArgs))
|
if (!array_key_exists('itop_version', $aArgs))
|
||||||
{
|
{
|
||||||
// Assume 1.0.2
|
// Assume 1.0.2
|
||||||
@@ -385,10 +392,10 @@ class ModuleDiscovery
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$sBooleanExpr = str_replace(array_keys($aReplacements), array_values($aReplacements), $sDepString);
|
$sBooleanExpr = str_replace(array_keys($aReplacements), array_values($aReplacements), $sDepString);
|
||||||
$bOk = @eval('$bResult = '.$sBooleanExpr.'; return true;');
|
try{
|
||||||
if ($bOk == false)
|
$bResult = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($sBooleanExpr);
|
||||||
{
|
} catch(ModuleFileReaderException $e){
|
||||||
SetupLog::Warning("Eval of '$sBooleanExpr' returned false");
|
//logged already
|
||||||
echo "Failed to parse the boolean Expression = '$sBooleanExpr'<br/>";
|
echo "Failed to parse the boolean Expression = '$sBooleanExpr'<br/>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -496,42 +503,12 @@ class ModuleDiscovery
|
|||||||
else if (preg_match('/^module\.(.*).php$/i', $sFile, $aMatches))
|
else if (preg_match('/^module\.(.*).php$/i', $sFile, $aMatches))
|
||||||
{
|
{
|
||||||
self::SetModulePath($sRelDir);
|
self::SetModulePath($sRelDir);
|
||||||
try
|
$sModuleFilePath = $sDirectory.'/'.$sFile;
|
||||||
{
|
try {
|
||||||
$sModuleFileContents = file_get_contents($sDirectory.'/'.$sFile);
|
$aModuleInfo = ModuleFileReader::GetInstance()->ReadModuleFileInformation($sDirectory.'/'.$sFile);
|
||||||
$sModuleFileContents = str_replace(array('<?php', '?>'), '', $sModuleFileContents);
|
SetupWebPage::AddModule($sModuleFilePath, $aModuleInfo[1], $aModuleInfo[2]);
|
||||||
$sModuleFileContents = str_replace('__FILE__', "'".addslashes($sDirectory.'/'.$sFile)."'", $sModuleFileContents);
|
} catch(ModuleFileReaderException $e){
|
||||||
preg_match_all('/class ([A-Za-z0-9_]+) extends ([A-Za-z0-9_]+)/', $sModuleFileContents, $aMatches);
|
continue;
|
||||||
//print_r($aMatches);
|
|
||||||
$idx = 0;
|
|
||||||
foreach($aMatches[1] as $sClassName)
|
|
||||||
{
|
|
||||||
if (class_exists($sClassName))
|
|
||||||
{
|
|
||||||
// rename the class inside the code to prevent a "duplicate class" declaration
|
|
||||||
// and change its parent class as well so that nobody will find it and try to execute it
|
|
||||||
$sModuleFileContents = str_replace($sClassName.' extends '.$aMatches[2][$idx], $sClassName.'_'.($iDummyClassIndex++).' extends DummyHandler', $sModuleFileContents);
|
|
||||||
}
|
|
||||||
$idx++;
|
|
||||||
}
|
|
||||||
$bRet = eval($sModuleFileContents);
|
|
||||||
|
|
||||||
if ($bRet === false)
|
|
||||||
{
|
|
||||||
SetupLog::Warning("Eval of $sRelDir/$sFile returned false");
|
|
||||||
}
|
|
||||||
|
|
||||||
//echo "<p>Done.</p>\n";
|
|
||||||
}
|
|
||||||
catch(ParseError $e)
|
|
||||||
{
|
|
||||||
// PHP 7
|
|
||||||
SetupLog::Warning("Eval of $sRelDir/$sFile caused an exception: ".$e->getMessage()." at line ".$e->getLine());
|
|
||||||
}
|
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
// Continue...
|
|
||||||
SetupLog::Warning("Eval of $sRelDir/$sFile caused an exception: ".$e->getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
155
setup/modulediscovery/ModuleFileParser.php
Normal file
155
setup/modulediscovery/ModuleFileParser.php
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
use PhpParser\Node\Expr\Assign;
|
||||||
|
use PhpParser\ParserFactory;
|
||||||
|
require_once APPROOT . 'sources/PhpParser/Evaluation/PhpExpressionEvaluator.php';
|
||||||
|
|
||||||
|
class ModuleFileParser {
|
||||||
|
private static ModuleFileParser $oInstance;
|
||||||
|
|
||||||
|
protected function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function GetInstance(): ModuleFileParser {
|
||||||
|
if (!isset(static::$oInstance)) {
|
||||||
|
static::$oInstance = new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function SetInstance(?ModuleFileParser $oInstance): void {
|
||||||
|
static::$oInstance = $oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sPhpContent
|
||||||
|
*
|
||||||
|
* @return \PhpParser\Node\Stmt[]|null
|
||||||
|
*/
|
||||||
|
public function ParsePhpCode(string $sPhpContent): ?array
|
||||||
|
{
|
||||||
|
$oParser = (new ParserFactory())->createForNewestSupportedVersion();
|
||||||
|
return $oParser->parse($sPhpContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sModuleFilePath
|
||||||
|
* @param \PhpParser\Node\Expr\Assign $oAssignation
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @throws \ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function GetModuleInformationFromAddModuleCall(string $sModuleFilePath, \PhpParser\Node\Stmt\Expression $oExpression) : ?array
|
||||||
|
{
|
||||||
|
/** @var Assign $oAssignation */
|
||||||
|
$oAssignation = $oExpression->expr;
|
||||||
|
if (false === ($oAssignation instanceof PhpParser\Node\Expr\StaticCall)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var PhpParser\Node\Expr\StaticCall $oAssignation */
|
||||||
|
|
||||||
|
if ("SetupWebPage" !== $oAssignation?->class?->name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("AddModule" !== $oAssignation?->name?->name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aArgs = $oAssignation?->args;
|
||||||
|
if (count($aArgs) != 3) {
|
||||||
|
throw new ModuleFileReaderException("Not enough parameters when calling SetupWebPage::AddModule", 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oModuleId = $aArgs[1];
|
||||||
|
if (false === ($oModuleId instanceof PhpParser\Node\Arg)) {
|
||||||
|
throw new ModuleFileReaderException("2nd parameter to SetupWebPage::AddModule call issue: " . get_class($oModuleId), 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var PhpParser\Node\Arg $oModuleId */
|
||||||
|
if (false === ($oModuleId->value instanceof PhpParser\Node\Scalar\String_)) {
|
||||||
|
throw new ModuleFileReaderException("2nd parameter to SetupWebPage::AddModule not a string: " . get_class($oModuleId->value), 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sModuleId = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oModuleId->value);
|
||||||
|
|
||||||
|
$oModuleConfigInfo = $aArgs[2];
|
||||||
|
if (false === ($oModuleConfigInfo instanceof PhpParser\Node\Arg)) {
|
||||||
|
throw new ModuleFileReaderException("3rd parameter to SetupWebPage::AddModule call issue: " . get_class($oModuleConfigInfo), 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var PhpParser\Node\Arg $oModuleConfigInfo */
|
||||||
|
if (false === ($oModuleConfigInfo->value instanceof PhpParser\Node\Expr\Array_)) {
|
||||||
|
throw new ModuleFileReaderException("3rd parameter to SetupWebPage::AddModule not an array: " . get_class($oModuleConfigInfo->value), 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$aModuleConfig = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oModuleConfigInfo->value);
|
||||||
|
|
||||||
|
if (! is_array($aModuleConfig)){
|
||||||
|
throw new ModuleFileReaderException("3rd parameter to SetupWebPage::AddModule not an array: " . get_class($oModuleConfigInfo->value), 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
$sModuleFilePath,
|
||||||
|
$sModuleId,
|
||||||
|
$aModuleConfig,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sModuleFilePath
|
||||||
|
* @param \PhpParser\Node\Stmt\If_ $oNode
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @throws \ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function GetModuleInformationFromIf(string $sModuleFilePath, \PhpParser\Node\Stmt\If_ $oNode) : ?array
|
||||||
|
{
|
||||||
|
$bCondition = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oNode->cond);
|
||||||
|
if ($bCondition) {
|
||||||
|
foreach ($oNode->stmts as $oSubNode) {
|
||||||
|
if ($oSubNode instanceof \PhpParser\Node\Stmt\Expression) {
|
||||||
|
$aModuleConfig = $this->GetModuleInformationFromAddModuleCall($sModuleFilePath, $oSubNode);
|
||||||
|
if (!is_null($aModuleConfig)) {
|
||||||
|
return $aModuleConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_null($oNode->elseifs)) {
|
||||||
|
foreach ($oNode->elseifs as $oElseIfSubNode) {
|
||||||
|
/** @var \PhpParser\Node\Stmt\ElseIf_ $oElseIfSubNode */
|
||||||
|
$bCondition = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oElseIfSubNode->cond);
|
||||||
|
if ($bCondition) {
|
||||||
|
return $this->GetModuleConfigurationFromStatement($sModuleFilePath, $oElseIfSubNode->stmts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_null($oNode->else)) {
|
||||||
|
return $this->GetModuleConfigurationFromStatement($sModuleFilePath, $oNode->else->stmts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetModuleConfigurationFromStatement(string $sModuleFilePath, array $aStmts) : ?array
|
||||||
|
{
|
||||||
|
foreach ($aStmts as $oSubNode) {
|
||||||
|
if ($oSubNode instanceof \PhpParser\Node\Stmt\Expression) {
|
||||||
|
$aModuleConfig = $this->GetModuleInformationFromAddModuleCall($sModuleFilePath, $oSubNode);
|
||||||
|
if (!is_null($aModuleConfig)) {
|
||||||
|
return $aModuleConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
167
setup/modulediscovery/ModuleFileReader.php
Normal file
167
setup/modulediscovery/ModuleFileReader.php
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/ModuleFileParser.php';
|
||||||
|
require_once __DIR__ . '/ModuleFileReaderException.php';
|
||||||
|
|
||||||
|
class ModuleFileReader {
|
||||||
|
private static ModuleFileReader $oInstance;
|
||||||
|
private static int $iDummyClassIndex = 0;
|
||||||
|
|
||||||
|
protected function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function GetInstance(): ModuleFileReader {
|
||||||
|
if (!isset(static::$oInstance)) {
|
||||||
|
static::$oInstance = new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function SetInstance(?ModuleFileReader $oInstance): void {
|
||||||
|
static::$oInstance = $oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the information from a module file (module.xxx.php)
|
||||||
|
* @param string $sModuleFile
|
||||||
|
* @return array
|
||||||
|
* @throws ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function ReadModuleFileInformation(string $sModuleFilePath) : array
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$aNodes = ModuleFileParser::GetInstance()->ParsePhpCode(file_get_contents($sModuleFilePath));
|
||||||
|
}
|
||||||
|
catch (PhpParser\Error $e) {
|
||||||
|
throw new \ModuleFileReaderException($e->getMessage(), 0, $e, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
foreach ($aNodes as $sKey => $oNode) {
|
||||||
|
if ($oNode instanceof \PhpParser\Node\Stmt\Expression) {
|
||||||
|
$aModuleInfo = ModuleFileParser::GetInstance()->GetModuleInformationFromAddModuleCall($sModuleFilePath, $oNode);
|
||||||
|
if (! is_null($aModuleInfo)){
|
||||||
|
$this->CompleteModuleInfoWithFilePath($aModuleInfo);
|
||||||
|
return $aModuleInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oNode instanceof PhpParser\Node\Stmt\If_) {
|
||||||
|
$aModuleInfo = ModuleFileParser::GetInstance()->GetModuleInformationFromIf($sModuleFilePath, $oNode);
|
||||||
|
if (! is_null($aModuleInfo)){
|
||||||
|
$this->CompleteModuleInfoWithFilePath($aModuleInfo);
|
||||||
|
return $aModuleInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(ModuleFileReaderException $e) {
|
||||||
|
// Continue...
|
||||||
|
throw $e;
|
||||||
|
} catch(Exception $e) {
|
||||||
|
// Continue...
|
||||||
|
throw new ModuleFileReaderException("Eval of $sModuleFilePath caused an exception: ".$e->getMessage(), 0, $e, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ModuleFileReaderException("No proper call to SetupWebPage::AddModule found in module file", 0, null, $sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the information from a module file (module.xxx.php)
|
||||||
|
* Warning: this method is using eval() function to load the ModuleInstallerAPI classes.
|
||||||
|
* Current method is never called at design/runtime. It is acceptable to use it during setup only.
|
||||||
|
* @param string $sModuleFile
|
||||||
|
* @return array
|
||||||
|
* @throws ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function ReadModuleFileInformationUnsafe(string $sModuleFilePath) : array
|
||||||
|
{
|
||||||
|
$aModuleInfo = []; // will be filled by the "eval" line below...
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$aMatches = [];
|
||||||
|
$sModuleFileContents = file_get_contents($sModuleFilePath);
|
||||||
|
$sModuleFileContents = str_replace(['<?php', '?>'], '', $sModuleFileContents);
|
||||||
|
$sModuleFileContents = str_replace('__FILE__', "'".addslashes($sModuleFilePath)."'", $sModuleFileContents);
|
||||||
|
preg_match_all('/class ([A-Za-z0-9_]+) extends ([A-Za-z0-9_]+)/', $sModuleFileContents, $aMatches);
|
||||||
|
//print_r($aMatches);
|
||||||
|
$idx = 0;
|
||||||
|
foreach($aMatches[1] as $sClassName)
|
||||||
|
{
|
||||||
|
if (class_exists($sClassName))
|
||||||
|
{
|
||||||
|
// rename any class declaration inside the code to prevent a "duplicate class" declaration
|
||||||
|
// and change its parent class as well so that nobody will find it and try to execute it
|
||||||
|
// Note: don't use the same naming scheme as ModuleDiscovery otherwise you 'll have the duplicate class error again !!
|
||||||
|
$sModuleFileContents = str_replace($sClassName.' extends '.$aMatches[2][$idx], $sClassName.'_Ext_'.(ModuleFileReader::$iDummyClassIndex++).' extends DummyHandler', $sModuleFileContents);
|
||||||
|
}
|
||||||
|
$idx++;
|
||||||
|
}
|
||||||
|
// Replace the main function call by an assignment to a variable, as an array...
|
||||||
|
$sModuleFileContents = str_replace(['SetupWebPage::AddModule', 'ModuleDiscovery::AddModule'], '$aModuleInfo = array', $sModuleFileContents);
|
||||||
|
eval($sModuleFileContents); // Assigns $aModuleInfo
|
||||||
|
|
||||||
|
if (count($aModuleInfo) === 0)
|
||||||
|
{
|
||||||
|
throw new ModuleFileReaderException("Eval of $sModuleFilePath did not return the expected information...");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->CompleteModuleInfoWithFilePath($aModuleInfo);
|
||||||
|
}
|
||||||
|
catch(ModuleFileReaderException $e)
|
||||||
|
{
|
||||||
|
// Continue...
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
catch(ParseError $e)
|
||||||
|
{
|
||||||
|
// Continue...
|
||||||
|
throw new ModuleFileReaderException("Eval of $sModuleFilePath caused a parse error: ".$e->getMessage()." at line ".$e->getLine());
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
// Continue...
|
||||||
|
throw new ModuleFileReaderException("Eval of $sModuleFilePath caused an exception: ".$e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
return $aModuleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Internal trick: additional path is added into the module info structure to handle ModuleInstallerAPI execution during setup
|
||||||
|
* @param array &$aModuleInfo
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function CompleteModuleInfoWithFilePath(array &$aModuleInfo)
|
||||||
|
{
|
||||||
|
if (count($aModuleInfo)==3) {
|
||||||
|
$aModuleInfo[2]['module_file_path'] = $aModuleInfo[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAndCheckModuleInstallerClass($aModuleInfo) : ?string
|
||||||
|
{
|
||||||
|
if (! isset($aModuleInfo['installer'])){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sModuleInstallerClass = $aModuleInfo['installer'];
|
||||||
|
if (!class_exists($sModuleInstallerClass)) {
|
||||||
|
$sModuleFilePath = $aModuleInfo['module_file_path'];
|
||||||
|
$this->ReadModuleFileInformationUnsafe($sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists($sModuleInstallerClass))
|
||||||
|
{
|
||||||
|
throw new CoreException("Wrong installer class: '$sModuleInstallerClass' is not a PHP class - Module: ".$aModuleInfo['label']);
|
||||||
|
}
|
||||||
|
if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI'))
|
||||||
|
{
|
||||||
|
throw new CoreException("Wrong installer class: '$sModuleInstallerClass' is not derived from 'ModuleInstallerAPI' - Module: ".$aModuleInfo['label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sModuleInstallerClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
setup/modulediscovery/ModuleFileReaderException.php
Normal file
23
setup/modulediscovery/ModuleFileReaderException.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ModuleFileReaderException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ModuleFileReaderException constructor.
|
||||||
|
*
|
||||||
|
* @param string $sMessage
|
||||||
|
* @param int $iHttpCode
|
||||||
|
* @param Exception|null $oPrevious
|
||||||
|
*/
|
||||||
|
public function __construct($sMessage, $iHttpCode = 0, Exception $oPrevious = null, $sModuleFile = null)
|
||||||
|
{
|
||||||
|
$e = new \Exception("");
|
||||||
|
|
||||||
|
$aContext = ['previous' => $oPrevious?->getMessage(), 'stack' => $e->getTraceAsString()];
|
||||||
|
if (!is_null($sModuleFile)) {
|
||||||
|
$aContext['module_file'] = $sModuleFile;
|
||||||
|
}
|
||||||
|
SetupLog::Warning($sMessage, null, $aContext);
|
||||||
|
parent::__construct($sMessage, $iHttpCode, $oPrevious);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,8 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
|
||||||
require_once APPROOT."setup/modulediscovery.class.inc.php";
|
require_once APPROOT."setup/modulediscovery.class.inc.php";
|
||||||
require_once APPROOT.'setup/modelfactory.class.inc.php';
|
require_once APPROOT.'setup/modelfactory.class.inc.php';
|
||||||
require_once APPROOT.'setup/compiler.class.inc.php';
|
require_once APPROOT.'setup/compiler.class.inc.php';
|
||||||
@@ -457,21 +459,17 @@ class RunTimeEnvironment
|
|||||||
{
|
{
|
||||||
if (!array_key_exists($oModule->GetName(), $aRet) && $oModule->IsAutoSelect())
|
if (!array_key_exists($oModule->GetName(), $aRet) && $oModule->IsAutoSelect())
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
$bSelected = false;
|
|
||||||
SetupInfo::SetSelectedModules($aRet);
|
SetupInfo::SetSelectedModules($aRet);
|
||||||
eval('$bSelected = ('.$oModule->GetAutoSelect().');');
|
try{
|
||||||
}
|
$bSelected = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($oModule->GetAutoSelect());
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$bSelected = false;
|
|
||||||
}
|
|
||||||
if ($bSelected)
|
if ($bSelected)
|
||||||
{
|
{
|
||||||
$aRet[$oModule->GetName()] = $oModule; // store the Id of the selected module
|
$aRet[$oModule->GetName()] = $oModule; // store the Id of the selected module
|
||||||
$bModuleAdded = true;
|
$bModuleAdded = true;
|
||||||
}
|
}
|
||||||
|
} catch(ModuleFileReaderException $e){
|
||||||
|
//do nothing. logged already
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1091,16 +1089,36 @@ class RunTimeEnvironment
|
|||||||
{
|
{
|
||||||
foreach($aAvailableModules as $sModuleId => $aModule)
|
foreach($aAvailableModules as $sModuleId => $aModule)
|
||||||
{
|
{
|
||||||
if (($sModuleId != ROOT_MODULE) && in_array($sModuleId, $aSelectedModules) &&
|
if (($sModuleId != ROOT_MODULE) && in_array($sModuleId, $aSelectedModules))
|
||||||
isset($aAvailableModules[$sModuleId]['installer']) )
|
|
||||||
{
|
{
|
||||||
$sModuleInstallerClass = $aAvailableModules[$sModuleId]['installer'];
|
$aArgs = [MetaModel::GetConfig(), $aModule['version_db'], $aModule['version_code']];
|
||||||
SetupLog::Info("Calling Module Handler: $sModuleInstallerClass::$sHandlerName(oConfig, {$aModule['version_db']}, {$aModule['version_code']})");
|
RunTimeEnvironment::CallInstallerHandler($aAvailableModules[$sModuleId], $sHandlerName, $aArgs);
|
||||||
$aCallSpec = array($sModuleInstallerClass, $sHandlerName);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call the given handler method for all selected modules having an installation handler
|
||||||
|
*
|
||||||
|
* @param array $aModuleInfo
|
||||||
|
* @param string $sHandlerName
|
||||||
|
* @param array $aArgs
|
||||||
|
*
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
public static function CallInstallerHandler(array $aModuleInfo, $sHandlerName, array $aArgs)
|
||||||
|
{
|
||||||
|
$sModuleInstallerClass = ModuleFileReader::GetInstance()->GetAndCheckModuleInstallerClass($aModuleInfo);
|
||||||
|
if (is_null($sModuleInstallerClass)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupLog::Info("Calling Module Handler: $sModuleInstallerClass::$sHandlerName", null, $aArgs);
|
||||||
|
$aCallSpec = [$sModuleInstallerClass, $sHandlerName];
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec))
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
call_user_func_array($aCallSpec, array(MetaModel::GetConfig(), $aModule['version_db'], $aModule['version_code']));
|
call_user_func_array($aCallSpec, $aArgs);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$sErrorMessage = "Module $sModuleId : error when calling module installer class $sModuleInstallerClass for $sHandlerName handler";
|
$sErrorMessage = "Module $sModuleId : error when calling module installer class $sModuleInstallerClass for $sHandlerName handler";
|
||||||
$aExceptionContextData = [
|
$aExceptionContextData = [
|
||||||
@@ -1114,8 +1132,6 @@ class RunTimeEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load data from XML files for the selected modules (structural data and/or sample data)
|
* Load data from XML files for the selected modules (structural data and/or sample data)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
|
||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
|
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
|
||||||
@@ -269,16 +271,16 @@ class InstallationFileService {
|
|||||||
foreach($this->GetAutoSelectModules() as $sModuleId => $aModule)
|
foreach($this->GetAutoSelectModules() as $sModuleId => $aModule)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$bSelected = false;
|
|
||||||
SetupInfo::SetSelectedModules($this->aSelectedModules);
|
SetupInfo::SetSelectedModules($this->aSelectedModules);
|
||||||
eval('$bSelected = ('.$aModule['auto_select'].');');
|
$bSelected = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($aModule['auto_select']);
|
||||||
if ($bSelected)
|
if ($bSelected)
|
||||||
{
|
{
|
||||||
// Modules in data/production-modules/ are considered as mandatory and always installed
|
// Modules in data/production-modules/ are considered as mandatory and always installed
|
||||||
$this->aSelectedModules[$sModuleId] = true;
|
$this->aSelectedModules[$sModuleId] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (ModuleFileReaderException $e) {
|
||||||
|
//logged already
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
|
||||||
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
||||||
require_once(APPROOT.'setup/parameters.class.inc.php');
|
require_once(APPROOT.'setup/parameters.class.inc.php');
|
||||||
@@ -1786,11 +1787,11 @@ EOF
|
|||||||
if (isset($aInfo['auto_select'])) {
|
if (isset($aInfo['auto_select'])) {
|
||||||
// Check the module selection
|
// Check the module selection
|
||||||
try {
|
try {
|
||||||
$bSelected = false;
|
|
||||||
SetupInfo::SetSelectedModules($aModules);
|
SetupInfo::SetSelectedModules($aModules);
|
||||||
eval('$bSelected = ('.$aInfo['auto_select'].');');
|
$bSelected = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($aInfo['auto_select']);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (ModuleFileReaderException $e) {
|
||||||
|
//logged already
|
||||||
$bSelected = false;
|
$bSelected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1864,15 +1865,8 @@ EOF
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$bSelected = false;
|
|
||||||
SetupInfo::SetSelectedModules($aModules);
|
SetupInfo::SetSelectedModules($aModules);
|
||||||
eval('$bSelected = ('.$aModule['auto_select'].');');
|
$bSelected = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($aModule['auto_select']);
|
||||||
}
|
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$sDisplayChoices .= '<li><b>Warning: auto_select failed with exception ('.$e->getMessage().') for module "'.$sModuleId.'"</b></li>';
|
|
||||||
$bSelected = false;
|
|
||||||
}
|
|
||||||
if ($bSelected)
|
if ($bSelected)
|
||||||
{
|
{
|
||||||
$aModules[$sModuleId] = true; // store the Id of the selected module
|
$aModules[$sModuleId] = true; // store the Id of the selected module
|
||||||
@@ -1880,6 +1874,12 @@ EOF
|
|||||||
$bModuleAdded = true;
|
$bModuleAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(ModuleFileReaderException $e)
|
||||||
|
{
|
||||||
|
//logged already
|
||||||
|
$sDisplayChoices .= '<li><b>Warning: auto_select failed with exception ('.$e->getMessage().') for module "'.$sModuleId.'"</b></li>';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while($bModuleAdded);
|
while($bModuleAdded);
|
||||||
|
|||||||
9
sources/PhpParser/Evaluation/AbstractExprEvaluator.php
Normal file
9
sources/PhpParser/Evaluation/AbstractExprEvaluator.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
abstract class AbstractExprEvaluator implements iExprEvaluator {
|
||||||
|
public function GetHandledExpressionTypes(): ?array {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
sources/PhpParser/Evaluation/ArrayDimFetchEvaluator.php
Normal file
28
sources/PhpParser/Evaluation/ArrayDimFetchEvaluator.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||||
|
|
||||||
|
class ArrayDimFetchEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return ArrayDimFetch::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var ArrayDimFetch $oExpr */
|
||||||
|
|
||||||
|
$var = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||||
|
if (is_null($var)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dim = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->dim);
|
||||||
|
if (is_null($var)){
|
||||||
|
return $dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $var[$dim] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
48
sources/PhpParser/Evaluation/ArrayEvaluator.php
Normal file
48
sources/PhpParser/Evaluation/ArrayEvaluator.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use ModuleFileReaderException;
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\Array_;
|
||||||
|
use PhpParser\Node\Expr\ConstFetch;
|
||||||
|
use PhpParser\Node\Scalar\Int_;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
|
||||||
|
class ArrayEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Array_::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var Array_ $oExpr */
|
||||||
|
$iIndex=0;
|
||||||
|
|
||||||
|
$aModuleInformation=[];
|
||||||
|
/** @var \PhpParser\Node\Expr\ArrayItem $oValue */
|
||||||
|
foreach ($oExpr->items as $oArrayItem){
|
||||||
|
if ($oArrayItem->key instanceof Int_||$oArrayItem->key instanceof String_||$oArrayItem->key instanceof ConstFetch) {
|
||||||
|
//dictionnary
|
||||||
|
$sKey = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oArrayItem->key);
|
||||||
|
if (is_null($sKey)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//array
|
||||||
|
$sKey = $iIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$oValue = $oArrayItem->value;
|
||||||
|
$oEvaluatuedValue = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oValue);
|
||||||
|
$aModuleInformation[$sKey]=$oEvaluatuedValue;
|
||||||
|
} catch(ModuleFileReaderException $e){
|
||||||
|
//required to support legacy below dump dependency
|
||||||
|
//'dependencies' => ['itop-config-mgmt/2.0.0'||'itop-structure/3.0.0']
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aModuleInformation;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sources/PhpParser/Evaluation/BinaryOpEvaluator.php
Normal file
18
sources/PhpParser/Evaluation/BinaryOpEvaluator.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp;
|
||||||
|
|
||||||
|
abstract class BinaryOpEvaluator extends AbstractExprEvaluator {
|
||||||
|
abstract function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed;
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var BinaryOp $oExpr */
|
||||||
|
|
||||||
|
return $this->EvaluateBinaryOperation(
|
||||||
|
PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->left),
|
||||||
|
PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->right));
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/BitwiseAndEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/BitwiseAndEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BitwiseAnd;
|
||||||
|
|
||||||
|
class BitwiseAndEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BitwiseAnd::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left & $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sources/PhpParser/Evaluation/BitwiseNotEvaluator.php
Normal file
18
sources/PhpParser/Evaluation/BitwiseNotEvaluator.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\BitwiseNot;
|
||||||
|
|
||||||
|
class BitwiseNotEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BitwiseNot::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var BitwiseNot $oExpr */
|
||||||
|
|
||||||
|
return ~ PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/BitwiseOrEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/BitwiseOrEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BitwiseOr;
|
||||||
|
|
||||||
|
class BitwiseOrEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BitwiseOr::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left | $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/BitwiseXorEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/BitwiseXorEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BitwiseXor;
|
||||||
|
|
||||||
|
class BitwiseXorEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BitwiseXor::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left ^ $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/BooleanAndEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/BooleanAndEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
||||||
|
|
||||||
|
class BooleanAndEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BooleanAnd::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left && $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sources/PhpParser/Evaluation/BooleanNotEvaluator.php
Normal file
18
sources/PhpParser/Evaluation/BooleanNotEvaluator.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\BooleanNot;
|
||||||
|
|
||||||
|
class BooleanNotEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BooleanNot::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var BooleanNot $oExpr */
|
||||||
|
|
||||||
|
return ! PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/BooleanOrEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/BooleanOrEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||||
|
|
||||||
|
class BooleanOrEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return BooleanOr::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left || $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
sources/PhpParser/Evaluation/CastEvaluator.php
Normal file
59
sources/PhpParser/Evaluation/CastEvaluator.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\Cast;
|
||||||
|
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||||
|
|
||||||
|
class CastEvaluator implements iExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetHandledExpressionTypes(): ?array {
|
||||||
|
return [
|
||||||
|
Cast\Array_::class,
|
||||||
|
Cast\Bool_::class,
|
||||||
|
Cast\Double::class,
|
||||||
|
Cast\Int_::class,
|
||||||
|
Cast\Object_::class,
|
||||||
|
Cast\String_::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
$oSubExpr = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->expr);
|
||||||
|
switch (get_class($oExpr)){
|
||||||
|
case Cast\Array_::class:
|
||||||
|
return (array) $oSubExpr;
|
||||||
|
|
||||||
|
case Cast\Bool_::class:
|
||||||
|
return (bool) $oSubExpr;
|
||||||
|
|
||||||
|
case Cast\Double::class:
|
||||||
|
/** @var Cast\Double $oExpr */
|
||||||
|
switch ($oExpr->getAttribute("kind")){
|
||||||
|
case Cast\Double::KIND_DOUBLE:
|
||||||
|
return (double) $oSubExpr;
|
||||||
|
|
||||||
|
case Cast\Double::KIND_FLOAT:
|
||||||
|
case Cast\Double::KIND_REAL:
|
||||||
|
return (float) $oSubExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Cast\Int_::class:
|
||||||
|
return (int) $oSubExpr;
|
||||||
|
|
||||||
|
case Cast\Object_::class:
|
||||||
|
return (object) $oSubExpr;
|
||||||
|
|
||||||
|
case Cast\String_::class:
|
||||||
|
return (string) $oSubExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
sources/PhpParser/Evaluation/ClassConstFetchEvaluator.php
Normal file
35
sources/PhpParser/Evaluation/ClassConstFetchEvaluator.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\ClassConstFetch;
|
||||||
|
|
||||||
|
class ClassConstFetchEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return ClassConstFetch::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var ClassConstFetch $oExpr */
|
||||||
|
|
||||||
|
$sClassName = $oExpr->class->name;
|
||||||
|
$sProperty = $oExpr->name->name;
|
||||||
|
|
||||||
|
if ('class' === $sProperty){
|
||||||
|
return $sClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($sClassName)){
|
||||||
|
$class = new \ReflectionClass($sClassName);
|
||||||
|
if (array_key_exists($sProperty, $class->getConstants())) {
|
||||||
|
$oReflectionConstant = $class->getReflectionConstant($sProperty);
|
||||||
|
if ($oReflectionConstant->isPublic()){
|
||||||
|
return $class->getConstant($sProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
sources/PhpParser/Evaluation/CoalesceEvaluator.php
Normal file
23
sources/PhpParser/Evaluation/CoalesceEvaluator.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Coalesce;
|
||||||
|
|
||||||
|
class CoalesceEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Coalesce::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var Coalesce $oExpr */
|
||||||
|
|
||||||
|
$oLeftEval = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->left);
|
||||||
|
if (! is_null($oLeftEval)) {
|
||||||
|
return $oLeftEval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->right);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
sources/PhpParser/Evaluation/ConcatEvaluator.php
Normal file
28
sources/PhpParser/Evaluation/ConcatEvaluator.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||||
|
|
||||||
|
class ConcatEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Concat::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
if (is_null($left) && is_null($right)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($left)){
|
||||||
|
return $right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($right)){
|
||||||
|
return $left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "$left" . "$right";
|
||||||
|
}
|
||||||
|
}
|
||||||
21
sources/PhpParser/Evaluation/ConstFetchEvaluator.php
Normal file
21
sources/PhpParser/Evaluation/ConstFetchEvaluator.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\ConstFetch;
|
||||||
|
|
||||||
|
class ConstFetchEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return ConstFetch::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var ConstFetch $oExpr */
|
||||||
|
if (defined($oExpr->name)){
|
||||||
|
return constant($oExpr->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/EqualEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/EqualEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Equal;
|
||||||
|
|
||||||
|
class EqualEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Equal::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left == $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
sources/PhpParser/Evaluation/FuncCallEvaluator.php
Normal file
44
sources/PhpParser/Evaluation/FuncCallEvaluator.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use ModuleFileReaderException;
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
use PhpParser\Node\Name;
|
||||||
|
use ReflectionFunction;
|
||||||
|
|
||||||
|
class FuncCallEvaluator extends AbstractExprEvaluator {
|
||||||
|
public const WHITELIST=[
|
||||||
|
"function_exists",
|
||||||
|
"class_exists",
|
||||||
|
"method_exists"
|
||||||
|
];
|
||||||
|
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return FuncCall::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var FuncCall $oExpr */
|
||||||
|
|
||||||
|
if ($oExpr->name instanceof Name){
|
||||||
|
$sFunction = $oExpr->name->name;
|
||||||
|
} else {
|
||||||
|
$sFunction = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||||
|
}
|
||||||
|
if (! in_array($sFunction, self::WHITELIST)){
|
||||||
|
throw new ModuleFileReaderException("FuncCall $sFunction not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
$aArgs=[];
|
||||||
|
foreach ($oExpr->args as $arg){
|
||||||
|
/** @var \PhpParser\Node\Arg $arg */
|
||||||
|
$aArgs[]=$arg->value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oReflectionFunction = new ReflectionFunction($sFunction);
|
||||||
|
return $oReflectionFunction->invoke(...$aArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/GreaterEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/GreaterEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Greater;
|
||||||
|
|
||||||
|
class GreaterEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Greater::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left > $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/GreaterOrEqualEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/GreaterOrEqualEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\GreaterOrEqual;
|
||||||
|
|
||||||
|
class GreaterOrEqualEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return GreaterOrEqual::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left >= $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/IdenticalEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/IdenticalEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Identical;
|
||||||
|
|
||||||
|
class IdenticalEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Identical::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left === $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
sources/PhpParser/Evaluation/IssetEvaluator.php
Normal file
30
sources/PhpParser/Evaluation/IssetEvaluator.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\ConstFetch;
|
||||||
|
use PhpParser\Node\Expr\Isset_;
|
||||||
|
|
||||||
|
class IssetEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Isset_::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var Isset_ $oExpr */
|
||||||
|
|
||||||
|
foreach ($oExpr->vars as $oVar){
|
||||||
|
try{
|
||||||
|
$var = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oVar);
|
||||||
|
if (is_null($var)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (\Throwable $t) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
48
sources/PhpParser/Evaluation/MethodCallEvaluator.php
Normal file
48
sources/PhpParser/Evaluation/MethodCallEvaluator.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
use ReflectionClass;
|
||||||
|
|
||||||
|
class MethodCallEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetHandledExpressionTypes(): ?array {
|
||||||
|
return [MethodCall::class, Expr\NullsafeMethodCall::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||||
|
if (is_null($oVar)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aArgs=[];
|
||||||
|
foreach ($oExpr->args as $arg){
|
||||||
|
/** @var \PhpParser\Node\Arg $arg */
|
||||||
|
$aArgs[]=$arg->value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oExpr->name instanceof Identifier){
|
||||||
|
$sName = $oExpr->name->name;
|
||||||
|
} else {
|
||||||
|
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||||
|
try{
|
||||||
|
$oMethod = $oReflectionClass->getMethod($sName);
|
||||||
|
if ($oMethod->isPublic()){
|
||||||
|
return $oMethod->invokeArgs($oVar, $aArgs);
|
||||||
|
}
|
||||||
|
} catch (\ReflectionException $t) {}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/ModEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/ModEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Mod;
|
||||||
|
|
||||||
|
class ModEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Mod::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left % $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/MulEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/MulEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Mul;
|
||||||
|
|
||||||
|
class MulEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Mul::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left * $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/NotEqualEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/NotEqualEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\NotEqual;
|
||||||
|
|
||||||
|
class NotEqualEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return NotEqual::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left != $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
121
sources/PhpParser/Evaluation/PhpExpressionEvaluator.php
Normal file
121
sources/PhpParser/Evaluation/PhpExpressionEvaluator.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use ModuleFileParser;
|
||||||
|
use ModuleFileReaderException;
|
||||||
|
use PhpParser\ConstExprEvaluator;
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
|
||||||
|
class PhpExpressionEvaluator {
|
||||||
|
private static PhpExpressionEvaluator $oInstance;
|
||||||
|
|
||||||
|
/** @var iExprEvaluator[] $aPhpParserEvaluators */
|
||||||
|
private static array $aPhpParserEvaluators;
|
||||||
|
private int $iMode=self::LIB_AND_FALLBACK;
|
||||||
|
|
||||||
|
protected function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const LIB_AND_FALLBACK=1;
|
||||||
|
const LIB_ONLY=2;
|
||||||
|
const ITOP_ALGO=3;
|
||||||
|
public function SetMode($iMode)
|
||||||
|
{
|
||||||
|
$this->iMode =$iMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function GetInstance(): PhpExpressionEvaluator {
|
||||||
|
if (!isset(static::$oInstance)) {
|
||||||
|
static::$oInstance = new static();
|
||||||
|
static::$aPhpParserEvaluators=[];
|
||||||
|
|
||||||
|
foreach (glob(__DIR__ . "/**Evaluator.php") as $sFile){
|
||||||
|
require_once $sFile;
|
||||||
|
require_once $sFile;
|
||||||
|
$sNamespace = 'Combodo\\iTop\PhpParser\\Evaluation\\';
|
||||||
|
$sClass = $sNamespace. str_replace(".php", "", basename($sFile));
|
||||||
|
$oReflectionClass = new \ReflectionClass($sClass);
|
||||||
|
if ($oReflectionClass->isInstantiable()
|
||||||
|
&& $oReflectionClass->implementsInterface(iExprEvaluator::class)){
|
||||||
|
$oClass = new $sClass;
|
||||||
|
|
||||||
|
if (! is_null($oClass->GetHandledExpressionType())){
|
||||||
|
static::RegisterEvaluator($oClass, $oClass->GetHandledExpressionType());
|
||||||
|
}
|
||||||
|
if (! is_null($oClass->GetHandledExpressionTypes())) {
|
||||||
|
foreach ($oClass->GetHandledExpressionTypes() as $sHandledExpressionType){
|
||||||
|
static::RegisterEvaluator($oClass, $sHandledExpressionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function RegisterEvaluator(iExprEvaluator $oClass, string $sHandledExpressionType)
|
||||||
|
{
|
||||||
|
if (array_key_exists($sHandledExpressionType, static::$aPhpParserEvaluators)){
|
||||||
|
throw new \CoreException("Another Evaluator class already deals with $sHandledExpressionType");
|
||||||
|
}
|
||||||
|
static::$aPhpParserEvaluators[$sHandledExpressionType] = $oClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function SetInstance(?PhpExpressionEvaluator $oInstance): void {
|
||||||
|
static::$oInstance = $oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function EvaluateExpression(Expr $oExpression) : mixed
|
||||||
|
{
|
||||||
|
if ($this->iMode===self::ITOP_ALGO){
|
||||||
|
return $this->EvaluateExpressionLocally($oExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->iMode==self::LIB_ONLY){
|
||||||
|
$oConstExprEvaluator = new ConstExprEvaluator();
|
||||||
|
} else {
|
||||||
|
$oConstExprEvaluator = new ConstExprEvaluator([$this, "EvaluateExpressionLocally"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oConstExprEvaluator->evaluateDirectly($oExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function EvaluateExpressionLocally(Expr $oExpression) : mixed
|
||||||
|
{
|
||||||
|
$sClass = get_class($oExpression);
|
||||||
|
$oPhpParserEvaluator = static::$aPhpParserEvaluators[$sClass] ?? null;
|
||||||
|
if (is_null($oPhpParserEvaluator)){
|
||||||
|
return $oExpression->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oPhpParserEvaluator->Evaluate($oExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sBooleanExpr
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function ParseAndEvaluateBooleanExpression(string $sBooleanExpr) : bool
|
||||||
|
{
|
||||||
|
return $this->ParseAndEvaluateExpression($sBooleanExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ParseAndEvaluateExpression(string $sExpr) : mixed
|
||||||
|
{
|
||||||
|
$sPhpContent = <<<PHP
|
||||||
|
<?php
|
||||||
|
$sExpr;
|
||||||
|
PHP;
|
||||||
|
try{
|
||||||
|
$aNodes = ModuleFileParser::GetInstance()->ParsePhpCode($sPhpContent);
|
||||||
|
$oExpr = $aNodes[0];
|
||||||
|
return $this->EvaluateExpression($oExpr->expr);
|
||||||
|
} catch (\Throwable $t) {
|
||||||
|
throw new ModuleFileReaderException("Eval of '$sExpr' caused an error:".$t->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
sources/PhpParser/Evaluation/PropertyFetchEvaluator.php
Normal file
41
sources/PhpParser/Evaluation/PropertyFetchEvaluator.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
use ReflectionClass;
|
||||||
|
|
||||||
|
class PropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetHandledExpressionTypes(): ?array {
|
||||||
|
return [PropertyFetch::class, Expr\NullsafePropertyFetch::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||||
|
if (is_null($oVar)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oExpr->name instanceof Identifier){
|
||||||
|
$sName = $oExpr->name->name;
|
||||||
|
} else {
|
||||||
|
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||||
|
try{
|
||||||
|
$oProperty = $oReflectionClass->getProperty($sName);
|
||||||
|
if ($oProperty->isPublic()){
|
||||||
|
return $oProperty->getValue($oVar);
|
||||||
|
}
|
||||||
|
} catch (\ReflectionException $t) {}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/SmallerEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/SmallerEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\Smaller;
|
||||||
|
|
||||||
|
class SmallerEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Smaller::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left < $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
sources/PhpParser/Evaluation/SmallerOrEqualEvaluator.php
Normal file
16
sources/PhpParser/Evaluation/SmallerOrEqualEvaluator.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\SmallerOrEqual;
|
||||||
|
|
||||||
|
class SmallerOrEqualEvaluator extends BinaryOpEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return SmallerOrEqual::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvaluateBinaryOperation(mixed $left, mixed $right) : mixed
|
||||||
|
{
|
||||||
|
return $left <= $right;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
sources/PhpParser/Evaluation/StaticCallEvaluator.php
Normal file
49
sources/PhpParser/Evaluation/StaticCallEvaluator.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use ModuleFileReaderException;
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
|
||||||
|
class StaticCallEvaluator extends AbstractExprEvaluator {
|
||||||
|
public const WHITELIST=[
|
||||||
|
"SetupInfo::ModuleIsSelected",
|
||||||
|
"utils::GetItopVersionWikiSyntax"
|
||||||
|
];
|
||||||
|
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return StaticCall::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var StaticCall $oExpr */
|
||||||
|
|
||||||
|
$sClassName = $oExpr->class->name;
|
||||||
|
if ($oExpr->name instanceof Identifier){
|
||||||
|
$sMethodName = $oExpr->name->name;
|
||||||
|
} else {
|
||||||
|
$sMethodName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sStaticCallDescription = "$sClassName::$sMethodName";
|
||||||
|
if (! in_array($sStaticCallDescription, self::WHITELIST)){
|
||||||
|
throw new ModuleFileReaderException("StaticCall $sStaticCallDescription not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
$aArgs=[];
|
||||||
|
foreach ($oExpr->args as $arg){
|
||||||
|
/** @var \PhpParser\Node\Arg $arg */
|
||||||
|
$aArgs[]=$arg->value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = new \ReflectionClass($sClassName);
|
||||||
|
$method = $class->getMethod($sMethodName);
|
||||||
|
if (! $method->isPublic()){
|
||||||
|
throw new ModuleFileReaderException("StaticCall $sStaticCallDescription not public");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $method->invokeArgs(null, $aArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
|
||||||
|
class StaticPropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return StaticPropertyFetch::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var StaticPropertyFetch $oExpr */
|
||||||
|
|
||||||
|
$sClassName = $oExpr->class->name;
|
||||||
|
if ($oExpr->name instanceof Identifier){
|
||||||
|
$sProperty = $oExpr->name->name;
|
||||||
|
} else {
|
||||||
|
$sProperty = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($sClassName)){
|
||||||
|
$class = new \ReflectionClass($sClassName);
|
||||||
|
if (array_key_exists($sProperty, $class->getStaticProperties())) {
|
||||||
|
$oReflectionProperty = $class->getProperty($sProperty);
|
||||||
|
if ($oReflectionProperty->isPublic()){
|
||||||
|
return $class->getStaticPropertyValue($sProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
sources/PhpParser/Evaluation/TernaryEvaluator.php
Normal file
24
sources/PhpParser/Evaluation/TernaryEvaluator.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\Ternary;
|
||||||
|
|
||||||
|
class TernaryEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Ternary::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var Ternary $oExpr */
|
||||||
|
|
||||||
|
$cond = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->cond);
|
||||||
|
|
||||||
|
if ($cond){
|
||||||
|
return PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->if);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->else);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sources/PhpParser/Evaluation/UnaryMinusEvaluator.php
Normal file
18
sources/PhpParser/Evaluation/UnaryMinusEvaluator.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\UnaryMinus;
|
||||||
|
|
||||||
|
class UnaryMinusEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return UnaryMinus::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var UnaryMinus $oExpr */
|
||||||
|
|
||||||
|
return - PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sources/PhpParser/Evaluation/UnaryPlusEvaluator.php
Normal file
18
sources/PhpParser/Evaluation/UnaryPlusEvaluator.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\UnaryPlus;
|
||||||
|
|
||||||
|
class UnaryPlusEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return UnaryPlus::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var UnaryPlus $oExpr */
|
||||||
|
|
||||||
|
return + PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
sources/PhpParser/Evaluation/VariableEvaluator.php
Normal file
28
sources/PhpParser/Evaluation/VariableEvaluator.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\Variable;
|
||||||
|
|
||||||
|
class VariableEvaluator extends AbstractExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string {
|
||||||
|
return Variable::class;
|
||||||
|
}
|
||||||
|
public function Evaluate(Expr $oExpr): mixed {
|
||||||
|
/** @var Variable $oExpr */
|
||||||
|
$sName = $oExpr->name;
|
||||||
|
|
||||||
|
if (array_key_exists($sName, get_defined_vars())) {
|
||||||
|
return $$sName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($sName, $GLOBALS)) {
|
||||||
|
global $$sName;
|
||||||
|
return $$sName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
sources/PhpParser/Evaluation/iExprEvaluator.php
Normal file
11
sources/PhpParser/Evaluation/iExprEvaluator.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
|
||||||
|
interface iExprEvaluator {
|
||||||
|
public function GetHandledExpressionType(): ?string;
|
||||||
|
public function GetHandledExpressionTypes(): ?array ;
|
||||||
|
public function Evaluate(Expr $oExpr) : mixed;
|
||||||
|
}
|
||||||
@@ -0,0 +1,235 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery;
|
||||||
|
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||||
|
use ModuleFileReader;
|
||||||
|
|
||||||
|
class ModuleFileReaderTest extends ItopDataTestCase
|
||||||
|
{
|
||||||
|
private string $sTempModuleFilePath;
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->RequireOnceItopFile('setup/modulediscovery/ModuleFileReader.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileInformationUnsafe()
|
||||||
|
{
|
||||||
|
$sModuleFilePath = __DIR__.'/resources/all/module.itop-full-itil.php';
|
||||||
|
$aRes = ModuleFileReader::GetInstance()->ReadModuleFileInformationUnsafe($sModuleFilePath);
|
||||||
|
|
||||||
|
$this->assertCount(3, $aRes);
|
||||||
|
$this->assertEquals($sModuleFilePath, $aRes[0]);
|
||||||
|
$this->assertEquals('itop-full-itil/3.3.0', $aRes[1]);
|
||||||
|
$this->assertIsArray($aRes[2]);
|
||||||
|
$this->assertArrayHasKey('label', $aRes[2]);
|
||||||
|
$this->assertEquals('Bridge - Request management ITIL + Incident management ITIL', $aRes[2]['label'] ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function ReadModuleFileConfigurationFileNameProvider()
|
||||||
|
{
|
||||||
|
$aUsecases=[];
|
||||||
|
foreach (glob(__DIR__.'/resources/all/*.php') as $sModuleFilePath){
|
||||||
|
$aUsecases[basename($sModuleFilePath)]=[$sModuleFilePath];
|
||||||
|
}
|
||||||
|
return $aUsecases;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider ReadModuleFileConfigurationFileNameProvider
|
||||||
|
*/
|
||||||
|
public function testReadModuleFileConfigurationVsLegacyMethod(string $sModuleFilePath)
|
||||||
|
{
|
||||||
|
$_SERVER=[
|
||||||
|
'SERVER_NAME' => 'titi'
|
||||||
|
];
|
||||||
|
$aRes = ModuleFileReader::GetInstance()->ReadModuleFileInformation($sModuleFilePath);
|
||||||
|
$aExpected = ModuleFileReader::GetInstance()->ReadModuleFileInformationUnsafe($sModuleFilePath);
|
||||||
|
|
||||||
|
$this->assertEquals($aExpected, $aRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Covers below legacy usecase
|
||||||
|
* 'dependencies' => array(
|
||||||
|
* 'itop-config-mgmt/2.0.0'||'itop-structure/3.0.0',
|
||||||
|
* 'itop-request-mgmt/2.0.0||itop-request-mgmt-itil/2.0.0||itop-incident-mgmt-itil/2.0.0',
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @param string $sModuleBasename
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
public function testReadModuleFileConfiguration_BadlyWrittenDependencies(){
|
||||||
|
$sModuleFilePath = __DIR__."/resources/all/module.itop-admin-delegation-profiles.php";
|
||||||
|
$aRes = ModuleFileReader::GetInstance()->ReadModuleFileInformation($sModuleFilePath);
|
||||||
|
$aExpected = ModuleFileReader::GetInstance()->ReadModuleFileInformationUnsafe($sModuleFilePath);
|
||||||
|
|
||||||
|
$this->assertEquals($aExpected, $aRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationParsingIssue()
|
||||||
|
{
|
||||||
|
$sModuleFilePath = __DIR__.'/resources/module.__MODULE__.php';
|
||||||
|
|
||||||
|
$this->expectException(\ModuleFileReaderException::class);
|
||||||
|
$this->expectExceptionMessage("Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ',' or ']' or ')' on line 31");
|
||||||
|
|
||||||
|
ModuleFileReader::GetInstance()->ReadModuleFileInformation($sModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* local tool function
|
||||||
|
*/
|
||||||
|
private function CallReadModuleFileConfiguration($sPHpCode)
|
||||||
|
{
|
||||||
|
$this->sTempModuleFilePath = tempnam(__DIR__, "test");
|
||||||
|
file_put_contents($this->sTempModuleFilePath, $sPHpCode);
|
||||||
|
try {
|
||||||
|
return ModuleFileReader::GetInstance()->ReadModuleFileInformation($this->sTempModuleFilePath);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
@unlink($this->sTempModuleFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatementWithoutIf()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
SetupWebPage::AddModule("a", "noif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "noif", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatement_IfConditionVerified()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
if (true){
|
||||||
|
SetupWebPage::AddModule("a", "if", ["c" => "d"]);
|
||||||
|
} elseif (true){
|
||||||
|
SetupWebPage::AddModule("a", "elseif1", ["c" => "d"]);
|
||||||
|
} elseif (true){
|
||||||
|
SetupWebPage::AddModule("a", "elseif2", ["c" => "d"]);
|
||||||
|
} else {
|
||||||
|
SetupWebPage::AddModule("a", "else", ["c" => "d"]);
|
||||||
|
}
|
||||||
|
SetupWebPage::AddModule("a", "outsideif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "if", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatement_IfNoConditionVerifiedAndNoElse()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
if (false){
|
||||||
|
SetupWebPage::AddModule("a", "if", ["c" => "d"]);
|
||||||
|
} elseif (false){
|
||||||
|
SetupWebPage::AddModule("a", "elseif1", ["c" => "d"]);
|
||||||
|
} elseif (false){
|
||||||
|
SetupWebPage::AddModule("a", "elseif2", ["c" => "d"]);
|
||||||
|
}
|
||||||
|
SetupWebPage::AddModule("a", "outsideif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "outsideif", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatement_ElseApplied()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
if (false){
|
||||||
|
SetupWebPage::AddModule("a", "if", ["c" => "d"]);
|
||||||
|
} elseif (false){
|
||||||
|
SetupWebPage::AddModule("a", "elseif1", ["c" => "d"]);
|
||||||
|
} elseif (false){
|
||||||
|
SetupWebPage::AddModule("a", "elseif2", ["c" => "d"]);
|
||||||
|
} else {
|
||||||
|
SetupWebPage::AddModule("a", "else", ["c" => "d"]);
|
||||||
|
}
|
||||||
|
SetupWebPage::AddModule("a", "outsideif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "else", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatement_FirstElseIfApplied()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
if (false){
|
||||||
|
SetupWebPage::AddModule("a", "if", ["c" => "d"]);
|
||||||
|
} elseif (true){
|
||||||
|
SetupWebPage::AddModule("a", "elseif1", ["c" => "d"]);
|
||||||
|
} elseif (true){
|
||||||
|
SetupWebPage::AddModule("a", "elseif2", ["c" => "d"]);
|
||||||
|
} else {
|
||||||
|
SetupWebPage::AddModule("a", "else", ["c" => "d"]);
|
||||||
|
}
|
||||||
|
SetupWebPage::AddModule("a", "outsideif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "elseif1", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadModuleFileConfigurationCheckBasicStatement_LastElseIfApplied()
|
||||||
|
{
|
||||||
|
$sPHP = <<<PHP
|
||||||
|
<?php
|
||||||
|
\$a=1;
|
||||||
|
if (false){
|
||||||
|
SetupWebPage::AddModule("a", "if", ["c" => "d"]);
|
||||||
|
} elseif (false){
|
||||||
|
SetupWebPage::AddModule("a", "elseif1", ["c" => "d"]);
|
||||||
|
} elseif (true){
|
||||||
|
SetupWebPage::AddModule("a", "elseif2", ["c" => "d"]);
|
||||||
|
} else {
|
||||||
|
SetupWebPage::AddModule("a", "else", ["c" => "d"]);
|
||||||
|
}
|
||||||
|
SetupWebPage::AddModule("a", "outsideif", ["c" => "d"]);
|
||||||
|
\$b=2;
|
||||||
|
PHP;
|
||||||
|
$val = $this->CallReadModuleFileConfiguration($sPHP);
|
||||||
|
$this->assertEquals([$this->sTempModuleFilePath, "elseif2", ["c" => "d", 'module_file_path' => $this->sTempModuleFilePath]], $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAndCheckModuleInstallerClass()
|
||||||
|
{
|
||||||
|
$sModuleInstallerClass = "TicketsInstaller" . uniqid();
|
||||||
|
$sPHpCode = file_get_contents(__DIR__.'/resources/all/module.itop-tickets.php');
|
||||||
|
$sPHpCode = str_replace("TicketsInstaller", $sModuleInstallerClass, $sPHpCode);
|
||||||
|
$this->sTempModuleFilePath = tempnam(__DIR__, "test");
|
||||||
|
file_put_contents($this->sTempModuleFilePath, $sPHpCode);
|
||||||
|
var_dump($sPHpCode);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->assertFalse(class_exists($sModuleInstallerClass));
|
||||||
|
$aModuleInfo = ModuleFileReader::GetInstance()->ReadModuleFileInformation($this->sTempModuleFilePath);
|
||||||
|
$this->assertFalse(class_exists($sModuleInstallerClass));
|
||||||
|
|
||||||
|
$this->assertEquals($sModuleInstallerClass, ModuleFileReader::GetInstance()->GetAndCheckModuleInstallerClass($aModuleInfo[2]));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
@unlink($this->sTempModuleFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue(class_exists($sModuleInstallerClass));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
// Until we develop a mean to adress this within the setup, let's check that this instance
|
||||||
|
// of PHP has the php_ldap extension
|
||||||
|
//
|
||||||
|
if (function_exists('ldap_connect'))
|
||||||
|
{
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'authent-ldap/3.3.0',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'User authentication based on LDAP',
|
||||||
|
'category' => 'authentication',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => true,
|
||||||
|
'installer' => 'AuthentLDAPInstaller',
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(
|
||||||
|
),
|
||||||
|
'data.struct' => array(
|
||||||
|
//'data.struct.authent-ldap.xml',
|
||||||
|
),
|
||||||
|
'data.sample' => array(
|
||||||
|
//'data.sample.authent-ldap.xml',
|
||||||
|
),
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '',
|
||||||
|
'doc.more_information' => '',
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(
|
||||||
|
'uri' => 'ldap://localhost', // URI with host or IP address of your LDAP server
|
||||||
|
'default_user' => '', // User and password used for initial "Anonymous" bind to LDAP
|
||||||
|
'default_pwd' => '', // Leave both blank, if anonymous (read-only) bind is allowed
|
||||||
|
'base_dn' => 'dc=yourcompany,dc=com', // Base DN for User queries, adjust it to your LDAP schema
|
||||||
|
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', // Query used to retrieve each user %1$s => iTop login
|
||||||
|
// For Windows AD use (samaccountname=%1$s) or (userprincipalname=%1$s)
|
||||||
|
|
||||||
|
// Some extra LDAP options, refer to: http://www.php.net/manual/en/function.ldap-set-option.php for more info
|
||||||
|
'options' => array(
|
||||||
|
LDAP_OPT_PROTOCOL_VERSION => 3,
|
||||||
|
LDAP_OPT_REFERRALS => 0,
|
||||||
|
),
|
||||||
|
'start_tls' => false,
|
||||||
|
'debug' => false,
|
||||||
|
'servers' => array(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Module installation handler
|
||||||
|
//
|
||||||
|
class AuthentLDAPInstaller extends ModuleInstallerAPI
|
||||||
|
{
|
||||||
|
public static function AfterDataLoad(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function BeforeWritingConfig(Config $oConfiguration)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if (function_exists('ldap_connect'))
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'combodo-email-synchro/3.8.2',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
'label' => 'Tickets synchronization via e-mail',
|
||||||
|
'category' => 'business',
|
||||||
|
// Setup
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-profiles-itil/3.0.0',
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => true,
|
||||||
|
'installer' => 'EmailSynchroInstaller',
|
||||||
|
// Components
|
||||||
|
'datamodel' => array(
|
||||||
|
'classes/autoload.php',
|
||||||
|
'model.combodo-email-synchro.php',
|
||||||
|
),
|
||||||
|
'dictionary' => array(),
|
||||||
|
'data.struct' => array(
|
||||||
|
),
|
||||||
|
'data.sample' => array(
|
||||||
|
),
|
||||||
|
// Documentation
|
||||||
|
'doc.manual_setup' => '', // No manual installation required
|
||||||
|
'doc.more_information' => '', // None
|
||||||
|
// Default settings
|
||||||
|
'settings' => array(
|
||||||
|
'notify_errors_to' => '', // mandatory to track errors not handled by the email processing module
|
||||||
|
'notify_errors_from' => '', // mandatory as well (can be set at the same value as notify_errors_to)
|
||||||
|
'debug' => false, // Set to true to turn on debugging
|
||||||
|
'periodicity' => 30, // interval at which to check for incoming emails (in s)
|
||||||
|
'retention_period' => 1, // number of hour we keep the replica
|
||||||
|
'body_parts_order' => 'text/html,text/plain', // Order in which to read the parts of the incoming emails
|
||||||
|
'pop3_auth_option' => 'USER',
|
||||||
|
'imap_options' => array('imap'),
|
||||||
|
'imap_open_options' => array(),
|
||||||
|
'maximum_email_size' => '10M', // Maximum allowed size for incoming emails
|
||||||
|
'big_files_dir' => '',
|
||||||
|
'exclude_attachment_types' => array('application/exe'), // Example: 'application/exe', 'application/x-winexe', 'application/msdos-windows'
|
||||||
|
// Lines to be removed just above the 'new part' in a reply-to message... add your own patterns below
|
||||||
|
'introductory-patterns' => array(
|
||||||
|
'/^le .+ a écrit :$/i', // Thunderbird French
|
||||||
|
'/^on .+ wrote:$/i', // Thunderbird English
|
||||||
|
'|^[0-9]{4}/[0-9]{1,2}/[0-9]{1,2} .+:$|', // Gmail style
|
||||||
|
),
|
||||||
|
// Some patterns which delimit the previous message in case of a Reply
|
||||||
|
// The "new" part of the message is the text before the pattern
|
||||||
|
// Add your own multi-line patterns (use \\R for a line break)
|
||||||
|
// These patterns depend on the mail client/server used... feel free to add your own discoveries to the list
|
||||||
|
'multiline-delimiter-patterns' => array(
|
||||||
|
'/\\RFrom: .+\\RSent: .+\\R/m', // Outlook English
|
||||||
|
'/\\R_+\\R/m', // A whole line made only of underscore characters
|
||||||
|
'/\\RDe : .+\\R\\R?Envoyé : /m', // Outlook French, HTML and rich text
|
||||||
|
'/\\RDe : .+\\RDate d\'envoi : .+\\R/m', // Outlook French, plain text
|
||||||
|
'/\\R-----Message d\'origine-----\\R/m',
|
||||||
|
),
|
||||||
|
'use_message_id_as_uid' => false, // Do NOT change this unless you known what you are doing!!
|
||||||
|
'images_minimum_size' => '100x20', // Images smaller that these dimensions will be ignored (signatures...)
|
||||||
|
'images_maximum_size' => '', // Images bigger that these dimensions will be resized before uploading into iTop
|
||||||
|
'recommended_max_allowed_packet' => 10*1024*1024, // MySQL parameter for attachments
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!class_exists('EmailSynchroInstaller'))
|
||||||
|
{
|
||||||
|
|
||||||
|
// Module installation handler
|
||||||
|
//
|
||||||
|
class EmailSynchroInstaller extends ModuleInstallerAPI
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called after the creation/update of the database schema
|
||||||
|
*
|
||||||
|
* @param $oConfiguration Config The new configuration of the application
|
||||||
|
* @param $sPreviousVersion string Previous version number of the module (empty string in case of first install)
|
||||||
|
* @param $sCurrentVersion string Current version number of the module
|
||||||
|
*
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
*/
|
||||||
|
public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
|
||||||
|
{
|
||||||
|
// For each email sources, update email replicas by setting mailbox_path to source.mailbox where mailbox_path is null
|
||||||
|
SetupLog::Info("Updating email replicas to set their mailbox path.");
|
||||||
|
|
||||||
|
// Preparing mailboxes search
|
||||||
|
$oSearch = new DBObjectSearch('MailInboxBase');
|
||||||
|
|
||||||
|
// Retrieving definition of attribute to update
|
||||||
|
$sTableName = MetaModel::DBGetTable('EmailReplica');
|
||||||
|
|
||||||
|
$UidlAttDef = MetaModel::GetAttributeDef('EmailReplica', 'uidl');
|
||||||
|
$sUidlColName = $UidlAttDef->Get('sql');
|
||||||
|
|
||||||
|
$oMailboxAttDef = MetaModel::GetAttributeDef('EmailReplica', 'mailbox_path');
|
||||||
|
$sMailboxColName = $oMailboxAttDef->Get('sql');
|
||||||
|
|
||||||
|
$sFrienlynameAttCode = MetaModel::GetFriendlyNameAttributeCode('EmailReplica');
|
||||||
|
|
||||||
|
// Looping on inboxes to update
|
||||||
|
$oSet = new DBObjectSet($oSearch);
|
||||||
|
while ($oInbox = $oSet->Fetch())
|
||||||
|
{
|
||||||
|
$sUpdateQuery = "UPDATE $sTableName SET $sMailboxColName = " . CMDBSource::Quote($oInbox->Get('mailbox')) . " WHERE $sUidlColName LIKE " . CMDBSource::Quote($oInbox->Get('login') . '_%') . " AND $sMailboxColName IS NULL";
|
||||||
|
SetupLog::Info("Executing query: " . $sUpdateQuery);
|
||||||
|
$iRet = CMDBSource::Query($sUpdateQuery); // Throws an exception in case of error
|
||||||
|
SetupLog::Info("Updated $iRet rows.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
//
|
||||||
|
// iTop module definition file
|
||||||
|
//
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'itop-admin-delegation-profiles-bridge-for-combodo-email-synchro/1.0.0',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'Profiles per admin fonction: Mail inboxes and messages',
|
||||||
|
'category' => 'Datamodel',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-admin-delegation-profiles/1.0.0',
|
||||||
|
'itop-admin-delegation-profiles/1.0.0 || combodo-email-synchro/3.7.2 || itop-oauth-client/2.7.7', // Optional dependency to silence the setup to not display a warning if the other module is not present
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => false,
|
||||||
|
'auto_select' => 'SetupInfo::ModuleIsSelected("itop-admin-delegation-profiles") && SetupInfo::ModuleIsSelected("combodo-email-synchro") && SetupInfo::ModuleIsSelected("itop-oauth-client")',
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(
|
||||||
|
'model.itop-admin-delegation-profiles-bridge-for-combodo-email-synchro.php'
|
||||||
|
),
|
||||||
|
'webservice' => array(
|
||||||
|
|
||||||
|
),
|
||||||
|
'data.struct' => array(
|
||||||
|
// add your 'structure' definition XML files here,
|
||||||
|
),
|
||||||
|
'data.sample' => array(
|
||||||
|
// add your sample data XML files here,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||||
|
'doc.more_information' => '', // hyperlink to more information, if any
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(
|
||||||
|
// Module specific settings go here, if any
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
//
|
||||||
|
// iTop module definition file
|
||||||
|
//
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'itop-admin-delegation-profiles/1.2.1',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'Profiles per admin fonction',
|
||||||
|
'category' => 'Datamodel',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-config-mgmt/2.7.0' || 'itop-structure/3.0.0',
|
||||||
|
// itop-profiles-itil is here to ensure that the /itop_design/groups/group[@id="History"] alteration comes after those from that module.
|
||||||
|
// This allows to define the missing "History" group in iTop 2.7 / 3.0, while merging smoothly with iTop 3.1+
|
||||||
|
'itop-profiles-itil/2.7.0',
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => true,
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(
|
||||||
|
'model.itop-admin-delegation-profiles.php'
|
||||||
|
),
|
||||||
|
'webservice' => array(
|
||||||
|
|
||||||
|
),
|
||||||
|
'data.struct' => array(
|
||||||
|
// add your 'structure' definition XML files here,
|
||||||
|
),
|
||||||
|
'data.sample' => array(
|
||||||
|
// add your sample data XML files here,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||||
|
'doc.more_information' => '', // hyperlink to more information, if any
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(
|
||||||
|
// Module specific settings go here, if any
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
//
|
||||||
|
// iTop module definition file
|
||||||
|
//
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'itop-full-itil/3.3.0',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'Bridge - Request management ITIL + Incident management ITIL',
|
||||||
|
'category' => 'business',
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-request-mgmt-itil/2.3.0',
|
||||||
|
'itop-incident-mgmt-itil/2.3.0',
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => false,
|
||||||
|
'auto_select' => 'SetupInfo::ModuleIsSelected("itop-request-mgmt-itil") && SetupInfo::ModuleIsSelected("itop-incident-mgmt-itil")',
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(),
|
||||||
|
'webservice' => array(),
|
||||||
|
'data.struct' => array(// add your 'structure' definition XML files here,
|
||||||
|
),
|
||||||
|
'data.sample' => array(// add your sample data XML files here,
|
||||||
|
),
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||||
|
'doc.more_information' => '', // hyperlink to more information, if any
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(// Module specific settings go here, if any
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module itop-global-requests
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2012-2019 Combodo SARL
|
||||||
|
* @license https://www.combodo.com/documentation/combodo-software-license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'itop-global-requests-mgmt/1.6.3',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'iTop Global Requests Management',
|
||||||
|
'category' => 'business',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-portal-base/3.2.0',
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => true,
|
||||||
|
'installer' => GlobalRequestInstaller::class,
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(
|
||||||
|
'vendor/autoload.php',
|
||||||
|
),
|
||||||
|
'webservice' => array(),
|
||||||
|
'data.struct' => array(// add your 'structure' definition XML files here,
|
||||||
|
),
|
||||||
|
'data.sample' => array(// add your sample data XML files here,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||||
|
'doc.more_information' => '', // hyperlink to more information, if any
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(
|
||||||
|
'target_state' => 'new',
|
||||||
|
'bypass_profiles' => 'Administrator, Service Manager',
|
||||||
|
'reuse_previous_answers' => true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalRequestInstaller extends ModuleInstallerAPI
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handler called before creating or upgrading the database schema
|
||||||
|
*
|
||||||
|
* @param $oConfiguration Config The new configuration of the application
|
||||||
|
* @param $sPreviousVersion string Previous version number of the module (empty string in case of first install)
|
||||||
|
* @param $sCurrentVersion string Current version number of the module
|
||||||
|
*
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
*/
|
||||||
|
public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
|
||||||
|
{
|
||||||
|
//code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__,
|
||||||
|
'itop-tickets/3.3.0',
|
||||||
|
array(
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => 'Tickets Management',
|
||||||
|
'category' => 'business',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => array(
|
||||||
|
'itop-structure/2.7.1',
|
||||||
|
),
|
||||||
|
'mandatory' => false,
|
||||||
|
'visible' => true,
|
||||||
|
'installer' => 'TicketsInstaller',
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => array(
|
||||||
|
'main.itop-tickets.php',
|
||||||
|
),
|
||||||
|
'data.struct' => array(
|
||||||
|
// 'data.struct.ta-actions.xml',
|
||||||
|
),
|
||||||
|
'data.sample' => array(
|
||||||
|
),
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '',
|
||||||
|
'doc.more_information' => '',
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => array(
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Module installation handler
|
||||||
|
//
|
||||||
|
class TicketsInstaller extends ModuleInstallerAPI
|
||||||
|
{
|
||||||
|
public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
|
||||||
|
{
|
||||||
|
// Delete all Triggers corresponding to a no more valid class
|
||||||
|
CMDBObject::SetTrackInfo('Uninstallation');
|
||||||
|
$oSearch = new DBObjectSearch('TriggerOnObject');
|
||||||
|
$oSet = new DBObjectSet($oSearch);
|
||||||
|
while($oTrigger = $oSet->Fetch())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!MetaModel::IsValidClass($oTrigger->Get('target_class')))
|
||||||
|
{
|
||||||
|
$oTrigger->DBDelete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// It's not very clear if it make sense to test a particular version,
|
||||||
|
// as the loading mechanism checks object existence using reconc_keys
|
||||||
|
// and do not recreate them, nor update existing.
|
||||||
|
// Without test, new entries added to the data files, would be automatically loaded
|
||||||
|
if (($sPreviousVersion === '') ||
|
||||||
|
(version_compare($sPreviousVersion, $sCurrentVersion, '<')
|
||||||
|
&& version_compare($sPreviousVersion, '3.0.0', '<'))) {
|
||||||
|
$oDataLoader = new XMLDataLoader();
|
||||||
|
|
||||||
|
CMDBObject::SetTrackInfo("Initialization TicketsInstaller");
|
||||||
|
$oMyChange = CMDBObject::GetCurrentChange();
|
||||||
|
|
||||||
|
$sLang = null;
|
||||||
|
// - Try to get app. language from configuration fil (app. upgrade)
|
||||||
|
$sConfigFileName = APPCONF.'production/'.ITOP_CONFIG_FILE;
|
||||||
|
if (file_exists($sConfigFileName)) {
|
||||||
|
$oFileConfig = new Config($sConfigFileName);
|
||||||
|
if (is_object($oFileConfig)) {
|
||||||
|
$sLang = str_replace(' ', '_', strtolower($oFileConfig->GetDefaultLanguage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - I still no language, get the default one
|
||||||
|
if (null === $sLang) {
|
||||||
|
$sLang = str_replace(' ', '_', strtolower($oConfiguration->GetDefaultLanguage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$sFileName = dirname(__FILE__)."/data/{$sLang}.data.itop-tickets.xml";
|
||||||
|
SetupLog::Info("Searching file: $sFileName");
|
||||||
|
if (!file_exists($sFileName)) {
|
||||||
|
$sFileName = dirname(__FILE__)."/data/en_us.data.itop-tickets.xml";
|
||||||
|
}
|
||||||
|
SetupLog::Info("Loading file: $sFileName");
|
||||||
|
$oDataLoader->StartSession($oMyChange);
|
||||||
|
$oDataLoader->LoadFile($sFileName, false, true);
|
||||||
|
$oDataLoader->EndSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-__YEAR__ Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// iTop module definition file
|
||||||
|
//
|
||||||
|
|
||||||
|
SetupWebPage::AddModule(
|
||||||
|
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||||
|
'__module_full_name__',
|
||||||
|
[
|
||||||
|
// Identification
|
||||||
|
//
|
||||||
|
'label' => '__module_label__',
|
||||||
|
'category' => '__module_category__',
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
//
|
||||||
|
'dependencies' => [
|
||||||
|
__module_dependencies__
|
||||||
|
],
|
||||||
|
'mandatory' => __module_mandatory__,
|
||||||
|
'visible' => __module_visible__,
|
||||||
|
__module_setup_handler_class__
|
||||||
|
|
||||||
|
// Components
|
||||||
|
//
|
||||||
|
'datamodel' => [
|
||||||
|
'vendor/autoload.php',
|
||||||
|
__module_data_model__, // Contains the PHP code generated by the "compilation" of datamodel.__module_name__.xml
|
||||||
|
],
|
||||||
|
'webservice' => [],
|
||||||
|
'data.struct' => [
|
||||||
|
// add your 'structure' definition XML files here,
|
||||||
|
],
|
||||||
|
'data.sample' => [
|
||||||
|
// add your sample data XML files here,
|
||||||
|
],
|
||||||
|
|
||||||
|
// Documentation
|
||||||
|
//
|
||||||
|
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||||
|
'doc.more_information' => '', // hyperlink to more information, if any
|
||||||
|
|
||||||
|
// Default settings
|
||||||
|
//
|
||||||
|
'settings' => [
|
||||||
|
// Module specific settings go here, if any
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
__module_setup_handler__
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Sources\PhpParser\Evaluation;
|
||||||
|
|
||||||
|
use Combodo\iTop\PhpParser\Evaluation\PhpExpressionEvaluator;
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||||
|
|
||||||
|
class PhpExpressionEvaluatorTest extends ItopDataTestCase {
|
||||||
|
public static $STATIC_PROPERTY = 123;
|
||||||
|
private static $PRIVATE_STATIC_PROPERTY = 123;
|
||||||
|
private const PRIVATE_CONSTANT = 123;
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
parent::tearDown(); // TODO: Change the autogenerated stub
|
||||||
|
PhpExpressionEvaluator::GetInstance()->SetMode(PhpExpressionEvaluator::ITOP_ALGO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function EvaluateExpressionProvider() {
|
||||||
|
return [
|
||||||
|
'Array: [1000 => "a"]' => ['sExpression' => '[1000 => "a"]'],
|
||||||
|
'Array: ["a"]' => ['sExpression' => '["a"]'],
|
||||||
|
'Array dict: ["a"=>"b"]' => ['sExpression' => '["a"=>"b"]'],
|
||||||
|
'ArrayDimFetch: $_SERVER[\'toto\']' => ['sExpression' => '$_SERVER[\'toto\']'],
|
||||||
|
'BinaryOperator: false|true' => [ 'sExpression' => 'false|true'],
|
||||||
|
'BinaryOperator: false||true' => [ 'sExpression' => 'false||true'],
|
||||||
|
'BinaryOperator: false&&true' => [ 'sExpression' => 'false&&true'],
|
||||||
|
'BinaryOperator: true&&true&&true&&false' => [ 'sExpression' => 'true && true && true && false'],
|
||||||
|
'BinaryOperator: false&true' => [ 'sExpression' => 'false&true'],
|
||||||
|
'BinaryOperator: ! true' => [ 'sExpression' => '! true'],
|
||||||
|
'BinaryOperator: 10 * 5' => [ 'sExpression' => '10 * 5'],
|
||||||
|
'BinaryOperator: 1 > 2' => [ 'sExpression' => '1 > 2'],
|
||||||
|
'BinaryOperator: 1 >= 1' => [ 'sExpression' => '1 >= 1'],
|
||||||
|
'BinaryOperator: 1 <= 1' => [ 'sExpression' => '1 <= 1'],
|
||||||
|
'BinaryOperator: PHP_VERSION_ID == PHP_VERSION_ID' => [ 'sExpression' => 'PHP_VERSION_ID == PHP_VERSION_ID'],
|
||||||
|
'BinaryOperator: PHP_VERSION_ID != PHP_VERSION_ID' => [ 'sExpression' => 'PHP_VERSION_ID != PHP_VERSION_ID'],
|
||||||
|
'BitwiseNot: ~3' => ['sExpression' => '~3'],
|
||||||
|
'BitwiseXor: 3^2' => ['sExpression' => '3^2'],
|
||||||
|
'BooleanAnd: true && false' => ['sExpression' => 'true && false'],
|
||||||
|
'Cast: (array)3' => ['sExpression' => '(array)3'],
|
||||||
|
'Cast: (bool)1' => ['sExpression' => '(bool)1'],
|
||||||
|
'Cast: (bool)0' => ['sExpression' => '(bool)0'],
|
||||||
|
'Cast: (double)3' => ['sExpression' => '(double)3'],
|
||||||
|
'Cast: (float)3' => ['sExpression' => '(float)3'],
|
||||||
|
'Cast: (int)3' => ['sExpression' => '(int)3'],
|
||||||
|
'Cast: (object)3' => ['sExpression' => '(object)3'],
|
||||||
|
'Cast: (string) $oEvaluationFakeClass' => ['sExpression' => '(string) $oEvaluationFakeClass', "toString"],
|
||||||
|
'ClassConstFetch: public existing constant' => [ 'sExpression' => 'SetupUtils::PHP_MIN_VERSION'],
|
||||||
|
'ClassConstFetch: unknown constant' => [ 'sExpression' => 'SetupUtils::UNKNOWN_CONSTANT'],
|
||||||
|
'ClassConstFetch: unknown class:constant' => [ 'sExpression' => 'GabuZomeuUnknownClass::UNKNOWN_CONSTANT'],
|
||||||
|
'ClassConstFetch: unknown class:class' => [ 'sExpression' => 'GabuZomeuUnknownClass::class'],
|
||||||
|
'ClassConstFetch: private existing constant' => [
|
||||||
|
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::PRIVATE_CONSTANT',
|
||||||
|
'forced_expected' => null,
|
||||||
|
],
|
||||||
|
'Coalesce: $oNullVar ?? 1' => ['sExpression' => '$oNullVar ?? 1', 1],
|
||||||
|
'Coalesce: $oNonNullVar ?? 1' => ['sExpression' => '$oNonNullVar ?? 1', 1],
|
||||||
|
'Coalesce: $_SERVER["toto"] ?? 1' => ['sExpression' => '$_SERVER["toto"] ?? 1', "titi"],
|
||||||
|
'Coalesce: $_SERVER["unknown_key"] ?? 1' => ['sExpression' => '$_SERVER["unknown_key"] ?? 1', 1],
|
||||||
|
'Coalesce: $oGlobalNonNullVar ?? 1' => ['sExpression' => '$oGlobalNonNullVar ?? 1', "a"],
|
||||||
|
'Coalesce: $oGlobalNullVar ?? 1' => ['sExpression' => '$oGlobalNullVar ?? 1', 1],
|
||||||
|
'Concat: "a"."b"' => ['sExpression' => '"a"."b"'],
|
||||||
|
'ConstFetch: false' => [ 'sExpression' => 'false'],
|
||||||
|
'ConstFetch: (false)' => [ 'sExpression' => 'false'],
|
||||||
|
'ConstFetch: true' => [ 'sExpression' => 'true'],
|
||||||
|
'ConstFetch: (true)' => [ 'sExpression' => 'true'],
|
||||||
|
'Equal: 1 == true' => [ 'sExpression' => '1 == true', true],
|
||||||
|
'Equal: 1 == false' => [ 'sExpression' => '1 == false', false],
|
||||||
|
'FuncCall: function_exists(\'ldap_connect\')' => [ 'sExpression' => 'function_exists(\'ldap_connect\')'],
|
||||||
|
'FuncCall: function_exists(\'gabuzomeushouldnotexist\')' => [ 'sExpression' => 'function_exists(\'gabuzomeushouldnotexist\')'],
|
||||||
|
'Identical: 1==="1"' => ['sExpression' => '1==="1"', false],
|
||||||
|
'Identical: "1"==="1"' => ['sExpression' => '"1"==="1"', true],
|
||||||
|
'Isset: isset($oNonNullVar)' => ['sExpression' => 'isset($oNonNullVar)', false],
|
||||||
|
'Isset: isset($oGlobalNonNullVar)' => ['sExpression' => 'isset($oGlobalNonNullVar)', true],
|
||||||
|
'Isset: isset($a, $_SERVER)' => ['sExpression' => 'isset($a, $_SERVER)', false],
|
||||||
|
'Isset: isset($_SERVER)' => ['sExpression' => 'isset($_SERVER)', true],
|
||||||
|
'Isset: isset($_SERVER, $a)' => ['sExpression' => 'isset($_SERVER, $a)', false],
|
||||||
|
'Isset: isset($oGlobalNonNullVar, $_SERVER)' => ['sExpression' => 'isset($oGlobalNonNullVar, $_SERVER)', true],
|
||||||
|
'MethodCall: $oEvaluationFakeClass->GetName()' => ['sExpression' => '$oEvaluationFakeClass->GetName()', "gabuzomeu"],
|
||||||
|
'MethodCall: $oEvaluationFakeClass->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass->GetLongName("aa")', "gabuzomeu_aa"],
|
||||||
|
'Mod: 3%2' => ['sExpression' => '3%2'],
|
||||||
|
'NullsafeMethodCall: $oNullVar?->GetName()' => ['sExpression' => '$oNullVar?->GetName()', null],
|
||||||
|
'NullsafeMethodCall: $oNullVar?->GetLongName("aa")' => ['sExpression' => '$oNullVar?->GetLongName("aa")', null],
|
||||||
|
'NullsafeMethodCall: $oEvaluationFakeClass?->GetName()' => ['sExpression' => '$oEvaluationFakeClass?->GetName()', "gabuzomeu"],
|
||||||
|
'NullsafeMethodCall: $oEvaluationFakeClass?->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass?->GetLongName("aa")', "gabuzomeu_aa"],
|
||||||
|
'NullsafePropertyFetch: $oNullVar?->b' => ['sExpression' => '$oNullVar?->b', null],
|
||||||
|
'NullsafePropertyFetch: $oEvaluationFakeClass?->iIsOk' => ['sExpression' => '$oEvaluationFakeClass?->iIsOk', "IsOkValue"],
|
||||||
|
'PropertyFetch: $oEvaluationFakeClass->iIsOk' => ['sExpression' => '$oEvaluationFakeClass->iIsOk', "IsOkValue"],
|
||||||
|
'StaticCall utils::GetItopVersionWikiSyntax()' => ['sExpression' => 'utils::GetItopVersionWikiSyntax()'],
|
||||||
|
'StaticProperty: public existing constant' => [ 'sExpression' => 'Combodo\iTop\Test\UnitTest\Sources\PhpParser\Evaluation\PhpExpressionEvaluatorTest::$STATIC_PROPERTY'],
|
||||||
|
'StaticProperty: private existing constant' => [
|
||||||
|
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::$PRIVATE_STATIC_PROPERTY',
|
||||||
|
'forced_expected' => null,
|
||||||
|
],
|
||||||
|
'Ternary: (true) ? 1 : 2' => ['sExpression' => '(true) ? 1 : 2'],
|
||||||
|
'Ternary: (false) ? 1 : 2' => ['sExpression' => '(false) ? 1 : 2'],
|
||||||
|
'UnaryMinus: -1' => ['sExpression' => '-1'],
|
||||||
|
'UnaryPlus: +1' => ['sExpression' => '+1'],
|
||||||
|
'Variable: $_SERVER' => ['sExpression' => '$_SERVER', ['toto' => 'titi']],
|
||||||
|
'Variable: $oNonNullVar' => ['sExpression' => '$oNonNullVar', null],
|
||||||
|
'Variable: $oGlobalNonNullVar' => ['sExpression' => '$oGlobalNonNullVar', "a"],
|
||||||
|
'Variable: $oEvaluationFakeClass' => ['sExpression' => '$oEvaluationFakeClass', new EvaluationFakeClass()],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider EvaluateExpressionProvider
|
||||||
|
*/
|
||||||
|
public function testEvaluateExpressionWithItopAlgo($sExpression, $forced_expected="NOTPROVIDED")
|
||||||
|
{
|
||||||
|
$this->evaluateExpressionWithMode($sExpression, $forced_expected, PhpExpressionEvaluator::ITOP_ALGO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider EvaluateExpressionProvider
|
||||||
|
*/
|
||||||
|
public function testEvaluateExpressionWithLibAndItopFallback($sExpression, $forced_expected="NOTPROVIDED")
|
||||||
|
{
|
||||||
|
$this->evaluateExpressionWithMode($sExpression, $forced_expected, PhpExpressionEvaluator::LIB_AND_FALLBACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function evaluateExpressionWithMode($sExpression, $forced_expected, $iMode)
|
||||||
|
{
|
||||||
|
global $oGlobalNonNullVar;
|
||||||
|
$oGlobalNonNullVar="a";
|
||||||
|
|
||||||
|
global $oGlobalNullVar;
|
||||||
|
$oGlobalNullVar=null;
|
||||||
|
|
||||||
|
$oNonNullVar="a";
|
||||||
|
|
||||||
|
$oNullVar=null;
|
||||||
|
$_SERVER=[
|
||||||
|
'toto' => 'titi',
|
||||||
|
];
|
||||||
|
|
||||||
|
global $oEvaluationFakeClass;
|
||||||
|
$oEvaluationFakeClass = new EvaluationFakeClass();
|
||||||
|
|
||||||
|
PhpExpressionEvaluator::GetInstance()->SetMode($iMode);
|
||||||
|
$res = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateExpression($sExpression);
|
||||||
|
if ($forced_expected === "NOTPROVIDED"){
|
||||||
|
$this->assertEquals($this->UnprotectedComputeExpression($sExpression), $res, $sExpression);
|
||||||
|
} else {
|
||||||
|
$this->assertEquals($forced_expected, $res, $sExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sBooleanExpr
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws \ModuleFileReaderException
|
||||||
|
*/
|
||||||
|
private function UnprotectedComputeExpression(string $sExpr) : mixed
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$bResult = null;
|
||||||
|
@eval('$bResult = '.$sExpr.';');
|
||||||
|
|
||||||
|
return $bResult;
|
||||||
|
} catch (\Throwable $t){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function ParseAndEvaluateBooleanExpression_AutoselectProvider()
|
||||||
|
{
|
||||||
|
$sSimpleCallToModuleIsSelected = "SetupInfo::ModuleIsSelected(\"itop-storage-mgmt\")";
|
||||||
|
$sSimpleCallToModuleIsSelected2 = "SetupInfo::ModuleIsSelected(\"itop-storage-mgmt-notselected\")";
|
||||||
|
$sCallToModuleIsSelectedCombinedWithAndOperator = "SetupInfo::ModuleIsSelected(\"itop-storage-mgmt\") || SetupInfo::ModuleIsSelected(\"itop-virtualization-mgmt\")";
|
||||||
|
$sCallToModuleIsSelectedCombinedWithAndOperator2 = "SetupInfo::ModuleIsSelected(\"itop-storage-mgmt-notselected\") || SetupInfo::ModuleIsSelected(\"itop-virtualization-mgmt\")";
|
||||||
|
|
||||||
|
return [
|
||||||
|
"simple call to SetupInfo::ModuleIsSelected SELECTED" => [
|
||||||
|
"expr" => $sSimpleCallToModuleIsSelected,
|
||||||
|
"expected" => true,
|
||||||
|
],
|
||||||
|
"simple call to SetupInfo::ModuleIsSelected NOT SELECTED" => [
|
||||||
|
"expr" => $sSimpleCallToModuleIsSelected2,
|
||||||
|
"expected" => false,
|
||||||
|
],
|
||||||
|
"call to SetupInfo::ModuleIsSelected + OR => SELECTED" => [
|
||||||
|
"expr" => $sCallToModuleIsSelectedCombinedWithAndOperator,
|
||||||
|
"expected" => true,
|
||||||
|
],
|
||||||
|
"simple call to SetupInfo::ModuleIsSelected + OR => NOT SELECTED" => [
|
||||||
|
"expr" => $sCallToModuleIsSelectedCombinedWithAndOperator2,
|
||||||
|
"expected" => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider ParseAndEvaluateBooleanExpression_AutoselectProvider
|
||||||
|
*/
|
||||||
|
public function testEvaluateBooleanExpression_Autoselect(string $sBooleanExpression, bool $expected){
|
||||||
|
\SetupInfo::SetSelectedModules(["itop-storage-mgmt" => "123"]);
|
||||||
|
$this->assertEquals($expected, PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateBooleanExpression($sBooleanExpression), $sBooleanExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EvaluationFakeClass {
|
||||||
|
public string $iIsOk="IsOkValue";
|
||||||
|
|
||||||
|
public function GetName()
|
||||||
|
{
|
||||||
|
return "gabuzomeu";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetLongName($suffix)
|
||||||
|
{
|
||||||
|
return "gabuzomeu_" . $suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString(): string
|
||||||
|
{
|
||||||
|
return "toString";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user