When importing data, we have the following scenarios
- The import file can contain
- a single language - with or without language code
- multiple languages - but only the primary-language will certainly contain all values, all other languages might be partially translated or refer to the value of other languages
- The target system could be
- singe language - without a language code
- single language - with a language code
- multiple languages - with a primary language that can differ from the import-system
After the import, the following should be achieved
- The target system must have all entities with real values for the primary-language of the target system
- The target system should have as many other values as possible pre-filled from the import-system
- If the languages don't match fully (like the import being for en-us, the target expecting en-uk), the target should contain the best fall-back
- The target system should have the same sharing of values as the source system (and the same read/write-sharing), so if the source shared the title in FR and ES and the target has these languages too, then the target should still share this value so that changing either FR or ES will change both
The logic at value-level
The language-matching happens at the lowest level, at the value level. The full logic used (for every single value) is as follows: Go through each attribute in source (so for example, look at the Teaser of a Content-Type Product) and do the following language-matchings for each target language.
- Go through each language in target, always do primary first, then all other target languages from A-Z
- Try to get a value for the current target language by doing this:
- Try to find exact language match (en-us for en-us) - if found, use this
- Otherwise try to find un-exact language match (e.g. en-uk for en-us)
- If there is exactly one un-exact language value, use this
- If there are multiple values (like target expects en-us, source has en-uk and en-au)
- If possible, use source primary language (if import had en-au as primary, use that)
- Otherwise try to find languages with matching country, because fr-fr is usually better than fr-ch
- If neither is the case, just use the first un-exact language when ordered by alphabet (so de-at comes before de-ch)
- If no value can be found
- If target language is primary (the primary cannot stay blank), then use source primary language
- If the target language we're trying to fill is not primary, it can stay blank (this will result in a fallback to the primary)
- Don't import yet, just assign the value (as pointer) – to the internal list of values to import
- If value has not been assigned, add with original ReadOnly state
Example: second target language is being matched and found. It should now point to the correct value and if the original pointer was read-only (like in shared-value situations), then it will also be read-only.
- If value has already been assigned to the list, add just dimension with original ReadOnly state
Example: this is the third language it's checking and it's using the same value as a language before (same meaning same pointer, not same text), then it also must use the same pointer and ensure that it has the same read/write relationship as in the original system.
- Set ReadOnly to false if target language is primary
Example: target primary is FR, source primary was EN. Then the original relationship could have been read-only, but the primary must always be read/write, so it's corrected.
- Correct ReadOnly states
- Sometimes we might import shared information resulting in all referring to this as a read-only relationship. This is technically correct but a hasslet to edit later on, so: Set ReadOnly to false on first language if ReadOnly for all languages (for a specific value) is true