Skip to content

Commit

Permalink
Merge pull request #657 from wikimedia/multiple-same-lang
Browse files Browse the repository at this point in the history
Fail earlier for multiple-text-same-lang structure
  • Loading branch information
MusikAnimal authored Dec 20, 2022
2 parents 19110bb + 109c44d commit 95334b0
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
2 changes: 1 addition & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

"structure-error-no-doc-element": "No document element found.",
"structure-error-nested-tspans-not-supported": "This file can not be translated because it contains nested tspan elements in $1.",
"structure-error-multiple-text-same-lang": "Multiple text elements found with language '$1'",
"structure-error-multiple-text-same-lang": "Multiple text elements found with language code '$2' (in element with ID '$1').",
"structure-error-contains-tref": "This file contains tref tags, which are not supported by this tool.",
"structure-error-css-too-complex": "This file contains CSS that is too complicated to parse.",
"structure-error-css-has-ids": "This file uses element IDs in the CSS, which may break when SVG Translate adds new IDs. It should use classes instead, if possible.",
Expand Down
2 changes: 1 addition & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"structure-error-css-has-ids": "Message displayed when an SVG file has an error that renders it untranslatable.",
"structure-error-unexpected-node-in-text": "Message displayed when an SVG file has an error that renders it untranslatable.",
"structure-error-invalid-node-id": "Message displayed when an SVG file has an error that renders it untranslatable.\n\nParameters:\n* $1 — Closest parent element ID.",
"structure-error-text-contains-dollar": "Message displayed when an SVG file has an error that renders it untranslatable.\n\nParameters:\n* $1 — Closest parent element ID.",
"structure-error-text-contains-dollar": "Message displayed when an SVG file has an error that renders it untranslatable.\n\nParameters:\n* $1 — Closest parent element ID.\n* $2 — Offending text content.",
"structure-error-non-tspan-inside-text": "Message displayed when an SVG file has an error that renders it untranslatable.",
"structure-error-switch-text-is-not-node": "Message displayed when an SVG file has an error that renders it untranslatable.",
"structure-error-switch-text-content-outside-text": "Message displayed when an SVG file has an error that renders it untranslatable.",
Expand Down
7 changes: 4 additions & 3 deletions src/Controller/TranslateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ public function translate(
return $this->showError('network-error', $normalizedFilename);
} catch (SvgStructureException $exception) {
$msgParams = $exception->getMessageParams();
// Get the element ID, or fall back to the no-ID placeholder message.
$id = $exception->getClosestId();
array_unshift($msgParams, $id ?: $intuition->msg('structure-error-no-id'));
// If there's no element ID fall back to the no-ID placeholder message.
if ($msgParams[0] === null) {
$msgParams[0] = $intuition->msg('structure-error-no-id');
}
return $this->showError(
$exception->getMessage(),
$normalizedFilename,
Expand Down
19 changes: 15 additions & 4 deletions src/Model/Svg/SvgFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,11 @@ protected function makeTranslationReady(): void
}
}

$textLength = $this->document->getElementsByTagName('text')->length;
$texts = $this->document->getElementsByTagName('text');
$textLength = $texts->length;
for ($i = 0; $i < $textLength; $i++) {
/** @var DOMElement $text */
$text = $this->document->getElementsByTagName('text')->item($i);
$text = $texts->item($i);

// Text strings like $1, $2 will cause problems later because
// self::replaceIndicesRecursive() will try to replace them
Expand Down Expand Up @@ -325,6 +326,7 @@ protected function makeTranslationReady(): void
for ($i = 0; $i < $switchLength; $i++) {
$switch = $this->document->getElementsByTagName('switch')->item($i);
$siblings = $switch->childNodes;
$existingLangs = [];
foreach ($siblings as $sibling) {
/** @var DOMElement $sibling */

Expand All @@ -344,6 +346,14 @@ protected function makeTranslationReady(): void
throw new SvgStructureException('structure-error-switch-child-not-text', $sibling);
}

// Make sure there's not more than one text element with the same lang.
$textLang = $sibling->getAttribute('systemLanguage');
if ( in_array( $textLang, $existingLangs ) ) {
throw new SvgStructureException('structure-error-multiple-text-same-lang', $switch, [$textLang]);
}
$existingLangs[] = $textLang;

// Check for comma-separated language codes (and reject the file if any duplicates are found).
$language = $sibling->hasAttribute('systemLanguage') ?
$sibling->getAttribute('systemLanguage') : 'fallback';
$realLangs = preg_split('/, */', $language);
Expand Down Expand Up @@ -616,8 +626,9 @@ public function switchToTranslationSet(array $translations): array
// No matching text node for this language, so we'll create one
$switch->appendChild($newTextTag);
} else {
// If there is more than existing text element in a switch (with the given lang), give up on this file.
throw new SvgStructureException('multiple-text-same-lang', $switch, [$language]);
// If there is more than one existing text element in a switch (with the given lang), give up on this file.
// This should never happen, because this same check is done in makeTranslationReady().
throw new SvgStructureException('structure-error-multiple-text-same-lang', $switch, [$language]);
}

// To have got this far, we must have either updated or started a new language
Expand Down
2 changes: 1 addition & 1 deletion tests/Model/Svg/SvgFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ public function testAddsTextToSwitch() {
. '</svg>');
$svgFile3->setTranslations('la', ['trsvg3' => 'lang la (new)']);
} catch (SvgStructureException $exception) {
$this->assertSame('multiple-text-same-lang', $exception->getMessage());
$this->assertSame('structure-error-multiple-text-same-lang', $exception->getMessage());
$this->assertSame(['testswitch', 'la'], $exception->getMessageParams());
}
}
Expand Down

0 comments on commit 95334b0

Please sign in to comment.