mirror of
https://github.com/Combodo/iTop.git
synced 2026-09-19 07:59:08 +02:00
N°9553 - Finalize localized sample and structural data
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Set>
|
||||
<NetworkDeviceType alias="NetworkDeviceType" id="10">
|
||||
<name>Router</name>
|
||||
</NetworkDeviceType>
|
||||
<NetworkDeviceType alias="NetworkDeviceType" id="11">
|
||||
<name>Switch</name>
|
||||
</NetworkDeviceType>
|
||||
</Set>
|
||||
@@ -25,14 +25,13 @@ SetupWebPage::AddModule(
|
||||
'main.itop-config-mgmt.php',
|
||||
],
|
||||
'data.struct' => [
|
||||
'data/en_us.data.itop-brand.xml',
|
||||
'data/en_us.data.itop-networkdevicetype.xml',
|
||||
'data/en_us.data.itop-osfamily.xml',
|
||||
'data/en_us.data.itop-osversion.xml',
|
||||
'data/data.itop-brand.xml',
|
||||
'data/data.itop-networkdevicetype.xml',
|
||||
'data/data.itop-osfamily.xml',
|
||||
'data/data.itop-osversion.xml',
|
||||
],
|
||||
'data.sample' => [
|
||||
'data/data.sample.model.xml',
|
||||
'data/data.sample.networkdevicetype.xml',
|
||||
'data/data.sample.servers.xml',
|
||||
'data/data.sample.nw-devices.xml',
|
||||
'data/data.sample.software.xml',
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Set>
|
||||
<ContactType alias="ContactType" id="17">
|
||||
<name>Customer manager</name>
|
||||
</ContactType>
|
||||
<ContactType alias="ContactType" id="12">
|
||||
<name>Helpdesk</name>
|
||||
</ContactType>
|
||||
<ContactType alias="ContactType" id="15">
|
||||
<name>Manager</name>
|
||||
</ContactType>
|
||||
<ContactType alias="ContactType" id="14">
|
||||
<name>Support Agent</name>
|
||||
</ContactType>
|
||||
<ContactType alias="ContactType" id="13">
|
||||
<name>Support level1</name>
|
||||
</ContactType>
|
||||
<ContactType alias="ContactType" id="16">
|
||||
<name>Team leader</name>
|
||||
</ContactType>
|
||||
</Set>
|
||||
@@ -32,7 +32,6 @@ SetupWebPage::AddModule(
|
||||
'data/data.sample.persons.xml',
|
||||
'data/data.sample.teams.xml',
|
||||
'data/data.sample.contactteam.xml',
|
||||
'data/data.sample.contacttype.xml',
|
||||
'data/data.sample.auditdomain.xml',
|
||||
'data/data.sample.auditcategory.xml',
|
||||
'data/data.sample.auditcategory-auditdomain.xml',
|
||||
|
||||
@@ -61,6 +61,6 @@ class TicketsInstaller extends ModuleInstallerAPI
|
||||
}
|
||||
}
|
||||
// Load localized structural data: predefined query phrases for notifications
|
||||
static::LoadLocalizedDataOnCrossingVersion($oConfiguration, $sPreviousVersion, $sCurrentVersion, '3.0.0', __DIR__."/data/data.itop-tickets.en_us.xml");
|
||||
static::LoadLocalizedDataOnCrossingVersion($oConfiguration, $sPreviousVersion, $sCurrentVersion, '3.0.0', utils::GetAbsoluteModulePath('itop-tickets')."/data/data.itop-tickets.en_us.xml");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,36 +326,11 @@ abstract class ModuleInstallerAPI
|
||||
public static function LoadLocalizedDataOnCrossingVersion(Config $oConfiguration, ?string $sPreviousVersion, ?string $sCurrentVersion, string $sFirstLoadingVersion, string $sDefaultFileName): void
|
||||
{
|
||||
self::AssertLoadLocalizedDataParametersAreValid($sPreviousVersion, $sCurrentVersion, $sFirstLoadingVersion);
|
||||
|
||||
// The loading is done only if
|
||||
// - it's a first install of the module
|
||||
// - or it's an upgrade of that module (PreviousVersion is less than the CurrentVersion), which means that we are really upgrading (and not reinstalling the same version or downgrading), and
|
||||
// - either the FirstLoadingVersion is between the PreviousVersion and the CurrentVersion
|
||||
// - or the FirstLoadingVersion is empty, forcing the loading on all upgrades,
|
||||
if (($sPreviousVersion === '') ||
|
||||
(version_compare($sPreviousVersion, $sCurrentVersion, '<')
|
||||
&& version_compare($sPreviousVersion, $sFirstLoadingVersion, '<')
|
||||
&& version_compare($sFirstLoadingVersion, $sCurrentVersion, '<='))) {
|
||||
|
||||
if (self::IsVersionCrossed($sPreviousVersion, $sCurrentVersion, $sFirstLoadingVersion)) {
|
||||
$sWishedLanguage = $oConfiguration->GetDefaultLanguage();
|
||||
self::LoadLocalizedData($sWishedLanguage, $sDefaultFileName);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Helper which will be removed as the standard knows how to load localized data on first install, but this is kept for backward compatibility.
|
||||
* @param \Config $oConfiguration
|
||||
* @param string $sPreviousVersion The previous version of the module (empty string in case of first install)
|
||||
* @param string $sFilePattern The pattern of the file to load, with {{language_code}} as placeholder for the language code (e.g. 'data.sample.{{language_code}}.xml')
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function LoadLocalizedDataOnNewInstall(Config $oConfiguration, ?string $sPreviousVersion, string $sFilePattern): void
|
||||
{
|
||||
if (utils::IsNullOrEmptyString($sPreviousVersion)) {
|
||||
$sWishedLanguage = $oConfiguration->GetDefaultLanguage();
|
||||
self::LoadLocalizedData($sWishedLanguage, $sFilePattern);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to load a localized data file based on the default language of the application.
|
||||
@@ -381,27 +356,6 @@ abstract class ModuleInstallerAPI
|
||||
$oDataLoader->EndSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
private static function AssertLoadLocalizedDataParametersAreValid(?string $sPreviousVersion, ?string $sCurrentVersion, string $sFirstLoadingVersion): void
|
||||
{
|
||||
if (($sPreviousVersion !== '') && !self::IsValidLocalizedDataVersion($sPreviousVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sPreviousVersion to be empty or match x.y[.z][-name], got '{$sPreviousVersion}'");
|
||||
}
|
||||
if (!self::IsValidLocalizedDataVersion($sCurrentVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sCurrentVersion to match x.y[.z][-name], got '{$sCurrentVersion}'");
|
||||
}
|
||||
if (($sFirstLoadingVersion !== '') && !self::IsValidLocalizedDataVersion($sFirstLoadingVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sFirstLoadingVersion to match x.y[.z][-name], got '{$sFirstLoadingVersion}'");
|
||||
}
|
||||
}
|
||||
|
||||
private static function IsValidLocalizedDataVersion(string $sVersion): bool
|
||||
{
|
||||
return (preg_match('/^\d+\.\d+(?:\.\d+)?(?:-[A-Za-z0-9]+)?$/', $sVersion) === 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the localized file name for a given language code, based on the original file name which must end by .en_us.xml
|
||||
* @param string $sLanguage The language code to use for localization (e.g. 'FR FR' or 'fr_fr')
|
||||
@@ -431,4 +385,40 @@ abstract class ModuleInstallerAPI
|
||||
}
|
||||
return $sFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
private static function AssertLoadLocalizedDataParametersAreValid(?string $sPreviousVersion, ?string $sCurrentVersion, string $sFirstLoadingVersion): void
|
||||
{
|
||||
if (($sPreviousVersion !== '') && !self::IsValidLocalizedDataVersion($sPreviousVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sPreviousVersion to be empty or match x.y[.z][-name], got '{$sPreviousVersion}'");
|
||||
}
|
||||
if (!self::IsValidLocalizedDataVersion($sCurrentVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sCurrentVersion to match x.y[.z][-name], got '{$sCurrentVersion}'");
|
||||
}
|
||||
if (($sFirstLoadingVersion !== '') && !self::IsValidLocalizedDataVersion($sFirstLoadingVersion)) {
|
||||
throw new CoreUnexpectedValue("LoadLocalizedData expects sFirstLoadingVersion to match x.y[.z][-name], got '{$sFirstLoadingVersion}'");
|
||||
}
|
||||
}
|
||||
|
||||
private static function IsValidLocalizedDataVersion(string $sVersion): bool
|
||||
{
|
||||
return (preg_match('/^\d+\.\d+(?:\.\d+)?(?:-[A-Za-z0-9]+)?$/', $sVersion) === 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sPreviousVersion
|
||||
* @param string|null $sCurrentVersion
|
||||
* @param string $sFirstLoadingVersion
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function IsVersionCrossed(?string $sPreviousVersion, ?string $sCurrentVersion, string $sFirstLoadingVersion): bool
|
||||
{
|
||||
return ($sPreviousVersion === '') ||
|
||||
(version_compare($sPreviousVersion, $sCurrentVersion, '<')
|
||||
&& version_compare($sPreviousVersion, $sFirstLoadingVersion, '<')
|
||||
&& version_compare($sFirstLoadingVersion, $sCurrentVersion, '<='));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1264,7 +1264,7 @@ class RunTimeEnvironment
|
||||
if (!file_exists($sFileName)) {
|
||||
throw(new Exception("File $sFileName does not exist"));
|
||||
}
|
||||
$sFileName = ModuleInstallerAPI::GetLocalizedFileName($sFileName, $sDefaultLanguage);
|
||||
$sFileName = ModuleInstallerAPI::GetLocalizedFileName($sDefaultLanguage, $sFileName);
|
||||
$oDataLoader->LoadFile($sFileName);
|
||||
$sResult = sprintf("loading of %s done.", basename($sFileName));
|
||||
SetupLog::Info($sResult);
|
||||
|
||||
@@ -334,53 +334,41 @@ SQL
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion
|
||||
* @dataProvider LoadLocalizedData_VersionConditionNotMetProvider
|
||||
* @covers \ModuleInstallerAPI::IsVersionCrossed
|
||||
* @dataProvider IsVersionCrossedProvider
|
||||
*/
|
||||
public function testLoadLocalizedData_DoesNotLoadWhenVersionConditionIsNotMet(string $sPreviousVersion, string $sCurrentVersion, string $sFirstLoadingVersion): void
|
||||
public function testIsVersionCrossed_ReturnsExpectedValue(string $sPreviousVersion, string $sCurrentVersion, string $sFirstLoadingVersion, bool $bExpected): void
|
||||
{
|
||||
// Given
|
||||
[$oConfig, $sOrgName, $sPattern] = $this->GivenLocalizedDataTestContext('XML_Load_NoLoad_', 'en_us', ['en_us']);
|
||||
// When version gate conditions are not met
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, $sPreviousVersion, $sCurrentVersion, $sFirstLoadingVersion, $sPattern);
|
||||
// Then no data loaded
|
||||
$this->AssertOrganizationCountByName($sOrgName, 'en_us', 0);
|
||||
$bIsVersionCrossed = $this->InvokeNonPublicStaticMethod(ModuleInstallerAPI::class, 'IsVersionCrossed', [$sPreviousVersion, $sCurrentVersion, $sFirstLoadingVersion]);
|
||||
|
||||
$this->assertSame($bExpected, $bIsVersionCrossed);
|
||||
}
|
||||
|
||||
public function LoadLocalizedData_VersionConditionNotMetProvider(): array
|
||||
public function IsVersionCrossedProvider(): array
|
||||
{
|
||||
return [
|
||||
'Equal versions (reinstall)' => ['3.1.0', '3.1.0', '3.0.0'],
|
||||
'Downgrade attempt' => ['3.2.0', '3.1.0', '3.0.0'],
|
||||
'Upgrade but first loading version already passed' => ['3.1.0', '3.2.0', '3.0.0'],
|
||||
'Upgrade with boundary equality on first loading version' => ['3.0.0', '3.1.0', '3.0.0'],
|
||||
'Upgrade but first loading version empty' => ['3.1.0', '3.2.0', ''],
|
||||
|
||||
'First install always crosses' => ['', '3.2.0', '3.0.0', true],
|
||||
'Upgrade crosses first loading version' => ['3.0.0', '3.2.0', '3.1.0', true],
|
||||
'Upgrade but first loading version already passed' => ['3.1.0', '3.2.0', '3.0.0', false],
|
||||
'Reinstall same version does not cross' => ['3.1.0', '3.1.0', '3.0.0', false],
|
||||
'Downgrade does not cross' => ['3.2.0', '3.1.0', '3.0.0', false],
|
||||
'First install with suffixed current version' => ['', '3.2-dev', '3.0.0', true],
|
||||
'Upgrade with suffixed current version crosses' => ['1.0.3-2', '1.2.4-1', '1.1.0', true],
|
||||
'Upgrade with suffixed current version below threshold does not cross' => ['1.0.0', '1.2.0-beta', '1.2.0', false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion
|
||||
* @dataProvider LoadLocalizedData_ValidVersionFormatsProvider
|
||||
*/
|
||||
public function testLoadLocalizedData_AcceptsSupportedVersionFormats(string $sCurrentVersion, string $sFirstLoadingVersion): void
|
||||
public function testLoadLocalizedData_LoadsWhenVersionCrossingIsTrue(): void
|
||||
{
|
||||
[$oConfig, $sOrgName, $sPattern] = $this->GivenLocalizedDataTestContext('XML_Load_ValidVersion_', 'en_us', ['en_us']);
|
||||
[$oConfig, $sOrgName, $sPattern] = $this->GivenLocalizedDataTestContext('XML_Load_VersionCrossingTrue_', 'en_us', ['en_us']);
|
||||
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '', $sCurrentVersion, $sFirstLoadingVersion, $sPattern);
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '3.0.0', '3.2.0', '3.1.0', $sPattern);
|
||||
|
||||
$this->AssertOrganizationCountByName($sOrgName, 'en_us', 1);
|
||||
}
|
||||
|
||||
public function LoadLocalizedData_ValidVersionFormatsProvider(): array
|
||||
{
|
||||
return [
|
||||
'Current version with suffix' => ['3.2-dev', '3.0.0'],
|
||||
'Current version x.y.z' => ['10.12.140-Tagada34', '1.0'],
|
||||
'Current version x.y.z-suffix' => ['2.3.3-beta', '2.3.3-alpha'],
|
||||
'Current version x.y.z-1' => ['1.2.4-1', '1.0.3-2'],
|
||||
];
|
||||
}
|
||||
// Test when a file is loaded twice because of the version conditions, it doesn't create duplicates (idempotent loading)
|
||||
public function testLoadLocalizedData_IdempotentLoading(): void
|
||||
{
|
||||
@@ -388,8 +376,8 @@ SQL
|
||||
[$oConfig, $sOrgName, $sPattern] = $this->GivenLocalizedDataTestContext('XML_Load_Idempotent_', 'en_us', ['en_us']);
|
||||
|
||||
// When LoadLocalizedData is called twice with conditions that would load the file both times
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '', '3.1.0', '3.0.0', $sPattern);
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '3.1.0', '3.2.0', '', $sPattern);
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '', '3.0.1', '3.0.0', $sPattern);
|
||||
ModuleInstallerAPI::LoadLocalizedDataOnCrossingVersion($oConfig, '3.0.1', '3.1.0', '3.0.2', $sPattern);
|
||||
|
||||
// Then no duplicate data loaded
|
||||
$this->AssertOrganizationCountByName($sOrgName, 'en_us', 1);
|
||||
@@ -420,30 +408,23 @@ SQL
|
||||
'previous' => 'v3.2',
|
||||
'current' => '3.2.0',
|
||||
'first' => '3.0.0',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.{{language_code}}.xml',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.en_us.xml',
|
||||
'message' => 'sPreviousVersion',
|
||||
],
|
||||
'Invalid current version format' => [
|
||||
'previous' => '',
|
||||
'current' => '3',
|
||||
'first' => '3.0.0',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.{{language_code}}.xml',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.en_us.xml',
|
||||
'message' => 'sCurrentVersion',
|
||||
],
|
||||
'Invalid first loading version format' => [
|
||||
'previous' => '',
|
||||
'current' => '3.2.0',
|
||||
'first' => '3.0.0-beta.1',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.{{language_code}}.xml',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.en_us.xml',
|
||||
'message' => 'sFirstLoadingVersion',
|
||||
],
|
||||
'Missing strict placeholder' => [
|
||||
'previous' => '',
|
||||
'current' => '3.2.0',
|
||||
'first' => '3.0.0',
|
||||
'pattern' => $sTmpDir.DIRECTORY_SEPARATOR.'data.{{LANGUAGE_CODE}}.xml',
|
||||
'message' => "{{language_code}}",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -462,7 +443,7 @@ SQL
|
||||
|
||||
$sTmpDir = static::CreateTmpdir();
|
||||
$this->aFileToClean[] = $sTmpDir;
|
||||
$sPattern = $sTmpDir.DIRECTORY_SEPARATOR.'data.{{language_code}}.xml';
|
||||
$sPattern = $sTmpDir.DIRECTORY_SEPARATOR.'data.en_us.xml';
|
||||
|
||||
foreach ($aAvailableLanguages as $sAvailableLanguage) {
|
||||
$this->GivenLocalizedDataFile($sTmpDir, $sAvailableLanguage, $sOrgName);
|
||||
|
||||
Reference in New Issue
Block a user