N°9553 - Fix on LoadLocalizedData in ModuleInstaller#926
Conversation
|
| Filename | Overview |
|---|---|
| setup/moduleinstaller.class.inc.php | Core refactor: replaces LoadLocalizedData with LoadLocalizedDataOnCrossingVersion + LoadLocalizedData + GetLocalizedFileName; naming convention changes from {{language_code}} pattern to .en_us.xml suffix-based; one stale @param doc and one misleading ?string type hint noted |
| setup/runtimeenv.class.inc.php | Adds ModuleInstallerAPI::GetLocalizedFileName call to the LoadData file loop so newly-installed modules resolve a localized data file based on the configured default language |
| datamodels/2.x/itop-tickets/module.itop-tickets.php | Updates AfterDatabaseCreation to call the new LoadLocalizedDataOnCrossingVersion with the absolute path to the en_us file instead of the old {{language_code}} pattern |
| tests/php-unit-tests/unitary-tests/setup/ModuleInstallerAPITest.php | Tests expanded with data providers covering language fallback, version-crossing logic, and idempotent loading; stale language-pattern tests removed |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["LoadLocalizedDataOnCrossingVersion"] --> B[AssertLoadLocalizedDataParametersAreValid]
B -->|invalid params| E[throw CoreUnexpectedValue]
B --> C{IsVersionCrossed?}
C -->|sPreviousVersion == ''| F[first install: true]
C -->|prev lt curr AND prev lt first AND first lte curr| G[upgrade crossing threshold: true]
C -->|otherwise| H[false: skip load]
F --> I["LoadLocalizedData(sWishedLanguage, sDefaultFile)"]
G --> I
I --> J["GetLocalizedFileName(sLanguage, sOriginalFile)"]
J -->|ends with .en_us.xml| K{localized file exists?}
K -->|yes| L[use localized file]
K -->|no| M[fall back to en_us file]
J -->|other extension| N[return file as-is]
L --> O[XMLDataLoader.LoadFile]
M --> O
N --> O
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["LoadLocalizedDataOnCrossingVersion"] --> B[AssertLoadLocalizedDataParametersAreValid]
B -->|invalid params| E[throw CoreUnexpectedValue]
B --> C{IsVersionCrossed?}
C -->|sPreviousVersion == ''| F[first install: true]
C -->|prev lt curr AND prev lt first AND first lte curr| G[upgrade crossing threshold: true]
C -->|otherwise| H[false: skip load]
F --> I["LoadLocalizedData(sWishedLanguage, sDefaultFile)"]
G --> I
I --> J["GetLocalizedFileName(sLanguage, sOriginalFile)"]
J -->|ends with .en_us.xml| K{localized file exists?}
K -->|yes| L[use localized file]
K -->|no| M[fall back to en_us file]
J -->|other extension| N[return file as-is]
L --> O[XMLDataLoader.LoadFile]
M --> O
N --> O
Reviews (2): Last reviewed commit: "N°9553 - Finalize localized sample and s..." | Re-trigger Greptile
|
@v-dumas I see that Olivier is set as "assignee" to the PR, did you mean "reviewer"? |
|
@Molkobain sorry, I fixed my error, you're right he is reviewer. |
b7b3f94 to
cfc019e
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes and hardens the localized structural-data loading mechanism used during module install/upgrade (ModuleInstallerAPI). The previous implementation relied on a {{language_code}} placeholder in the file pattern and a version guard that could load data too early during upgrades. The refactor switches to a .en_us.xml-suffix naming convention with a dedicated GetLocalizedFileName resolver, splits responsibilities into IsVersionCrossed + LoadLocalizedDataOnCrossingVersion, and adds a first <= current clause so data is only loaded when the "first loading version" is actually crossed by the upgrade.
Changes:
- Refactor
LoadLocalizedDataintoLoadLocalizedDataOnCrossingVersion(version-gate) +LoadLocalizedData(file load) +GetLocalizedFileName(suffix-based localization with en_us fallback), and correct the version-crossing condition. - Migrate
itop-ticketsnotification query data to localizeddata.itop-tickets.<lang>.xmlfiles (en_us/fr_fr/de_de) and update the module handler; also apply localization inruntimeenvLoadData. - Remove sample
contacttype/networkdevicetypeXML files (already provided by structural data) and rewrite the unit tests with data providers.
Reviewed changes
Copilot reviewed 8 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| setup/moduleinstaller.class.inc.php | Core refactor of localized data loading and version-crossing logic; docblocks partly stale |
| setup/runtimeenv.class.inc.php | Resolves localized file names in LoadData; clarified log message |
| datamodels/2.x/itop-tickets/module.itop-tickets.php | Calls new LoadLocalizedDataOnCrossingVersion with .en_us.xml base path |
| datamodels/2.x/itop-tickets/data/data.itop-tickets.en_us.xml | New English notification query data (base/fallback file) |
| datamodels/2.x/itop-tickets/data/data.itop-tickets.fr_fr.xml | New French localized notification query data |
| datamodels/2.x/itop-tickets/data/data.itop-tickets.de_de.xml | New German localized notification query data |
| datamodels/2.x/itop-structure/module.itop-structure.php | Drops sample contacttype file reference |
| datamodels/2.x/itop-structure/data/data.sample.contacttype.xml | Deleted (duplicated by structural contact-type data) |
| datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php | Drops sample networkdevicetype file reference |
| datamodels/2.x/itop-config-mgmt/data/data.sample.networkdevicetype.xml | Deleted (duplicated by structural network-device-type data) |
| tests/php-unit-tests/unitary-tests/setup/ModuleInstallerAPITest.php | Rewrites tests with data providers covering new methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
b6f4b31 to
24713bc
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| @@ -0,0 +1,101 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| @@ -0,0 +1,387 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| @@ -0,0 +1,219 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| @@ -0,0 +1,101 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| @@ -0,0 +1,387 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| if (($sFirstLoadingVersion !== '') && !self::IsValidLocalizedDataVersion($sFirstLoadingVersion)) { | ||
| throw new CoreUnexpectedValue("LoadLocalizedData expects sFirstLoadingVersion to match x.y[.z][-name], got '{$sFirstLoadingVersion}'"); | ||
| } |
| * @throws \CoreUnexpectedValue | ||
| */ | ||
| private static function AssertLoadLocalizedDataParametersAreValid(string $sPreviousVersion, string $sCurrentVersion, string $sFirstLoadingVersion, string $sFilePattern): void | ||
| private static function AssertLoadLocalizedDataParametersAreValid(?string $sPreviousVersion, ?string $sCurrentVersion, string $sFirstLoadingVersion): void |
| @@ -0,0 +1,18 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
Base information
Proposed solution (bug and enhancement)
Improve code and tests
Checklist before requesting a review