Skip to content

Commit 241899f

Browse files
authored
Merge pull request #225 from asmecher/xliff-set-ids
#224 Allow for setting custom ID to avoid translation clobbering
2 parents a545ffb + 3384000 commit 241899f

5 files changed

Lines changed: 66 additions & 15 deletions

File tree

src/Extractors/Xliff.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@
1111
*/
1212
class Xliff extends Extractor implements ExtractorInterface
1313
{
14+
15+
public static $options = [
16+
'unitid_as_id' => false
17+
];
18+
1419
/**
1520
* {@inheritdoc}
1621
*/
1722
public static function fromString($string, Translations $translations, array $options = [])
1823
{
24+
$options += static::$options;
25+
1926
$xml = new SimpleXMLElement($string, null, false);
2027

2128
foreach ($xml->file as $file) {
@@ -35,7 +42,11 @@ public static function fromString($string, Translations $translations, array $op
3542

3643
$translation = new Translation(null, (string) $segment->source);
3744
if (isset($unit['id'])) {
38-
$translation->addComment("XLIFF_UNIT_ID: $unit[id]");
45+
$unitId = (string) $unit['id'];
46+
$translation->addComment("XLIFF_UNIT_ID: $unitId");
47+
if ($options['unitid_as_id']) {
48+
$translation->setId($unitId);
49+
}
3950
}
4051
$translation->setTranslation(array_shift($targets));
4152
$translation->setPluralTranslations($targets);

src/Translation.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
class Translation
99
{
10+
protected $id;
1011
protected $context;
1112
protected $original;
1213
protected $translation = '';
@@ -69,14 +70,30 @@ public function getClone($context = null, $original = null)
6970
return $new;
7071
}
7172

73+
/**
74+
* Sets the id of this translation.
75+
* @warning The use of this function to set a custom ID will prevent
76+
* Translations::find from matching this translation.
77+
*
78+
* @param string $id
79+
*/
80+
public function setId($id)
81+
{
82+
$this->id = $id;
83+
}
84+
85+
7286
/**
7387
* Returns the id of this translation.
7488
*
7589
* @return string
7690
*/
7791
public function getId()
7892
{
79-
return static::generateId($this->context, $this->original);
93+
if ($this->id === null) {
94+
return static::generateId($this->context, $this->original);
95+
}
96+
return $this->id;
8097
}
8198

8299
/**

src/Translations.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ public function hasDomain()
413413
*
414414
* @param string|Translation $context The context of the translation or a translation instance
415415
* @param string $original The original string
416+
* @warning Translations with custom identifiers (e.g. XLIFF unit IDs) cannot be found using this function.
416417
*
417418
* @return Translation|false
418419
*/

tests/AssetsTest.php

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -548,25 +548,38 @@ public function testVueJs2MultipleDomainScanning()
548548
}
549549
}
550550

551-
public function testXliff()
551+
public function testXliffUnitIds()
552552
{
553-
$translations = static::get('xliff/Xliff', 'Xliff');
554-
$countTranslations = 2;
555-
$countTranslated = 2;
553+
$translations = static::get('xliff/Xliff', 'Xliff', ['unitid_as_id' => true]);
554+
$countTranslations = 3;
555+
$countTranslated = 3;
556556
$countHeaders = 9;
557557

558558
$this->assertCount($countTranslations, $translations);
559559
$this->assertCount($countHeaders, $translations->getHeaders());
560-
$this->assertEquals(2, $translations->countTranslated());
561-
562-
$translation1 = $translations->find(null, 'one file');
563-
$this->assertEquals(\Gettext\Generators\Xliff::getUnitID($translation1), 'custom.unit.id');
564-
565-
$translation2 = $translations->find(null, 'one');
566-
$this->assertEquals(\Gettext\Generators\Xliff::getUnitID($translation2), 'second.custom.unit.id');
560+
$this->assertEquals($countTranslated, $translations->countTranslated());
567561

568-
$this->assertContent($translations, 'xliff/Po');
562+
foreach ($translations as $translation) {
563+
switch (\Gettext\Generators\Xliff::getUnitID($translation)) {
564+
case 'custom.unit.id':
565+
$this->assertEquals($translation->getOriginal(), 'one file');
566+
$this->assertEquals($translation->getTranslation(), '1 plik');
567+
break;
568+
case 'second.custom.unit.id':
569+
$this->assertEquals($translation->getOriginal(), 'one');
570+
$this->assertEquals($translation->getTranslation(), '1');
571+
break;
572+
case 'duplicate.source.unit.id':
573+
$this->assertEquals($translation->getOriginal(), 'one');
574+
$this->assertEquals($translation->getTranslation(), 'uno');
575+
break;
576+
default:
577+
$this->assertFalse(true);
578+
}
579+
}
569580

570-
$this->runTestFormat('xliff/Po', $countTranslations, $countTranslated, $countHeaders);
581+
// Converting from an XLIFF that contains duplicate <source> elements
582+
// to a PO file will result in the loss of the duplicates.
583+
$this->runTestFormat('xliff/Po', $countTranslations-1, $countTranslated-1, $countHeaders);
571584
}
572585
}

tests/assets/xliff/Xliff.xlf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,14 @@
3131
<target>1</target>
3232
</segment>
3333
</unit>
34+
<unit id="duplicate.source.unit.id">
35+
<notes>
36+
<note category="context"></note>
37+
</notes>
38+
<segment>
39+
<source>one</source>
40+
<target>uno</target>
41+
</segment>
42+
</unit>
3443
</file>
3544
</xliff>

0 commit comments

Comments
 (0)