Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
XliffFFS.php
Go to the documentation of this file.
1<?php
15class XliffFFS extends SimpleFFS {
16 public static function isValid( $data ) {
17 $doc = new DomDocument( '1.0' );
18 $doc->loadXML( $data );
19
20 $errors = libxml_get_errors();
21 if ( $errors ) {
22 return false;
23 }
24
25 if ( strpos( $data, 'version="1.2">' ) !== false ) {
26 $schema = __DIR__ . '/../data/xliff-core-1.2-transitional.xsd';
27 if ( !$doc->schemaValidate( $schema ) ) {
28 return false;
29 }
30 }
31
32 return true;
33 }
34
35 public function getFileExtensions() {
36 return [ '.xlf', '.xliff', '.xml' ];
37 }
38
44 public function readFromVariable( $data, $element = 'target' ) {
45 $messages = [];
46 $mangler = $this->group->getMangler();
47
48 $reader = new SimpleXMLElement( $data );
49 $reader->registerXPathNamespace(
50 'xliff',
51 'urn:oasis:names:tc:xliff:document:1.2'
52 );
53
54 $items = array_merge(
55 $reader->xpath( '//trans-unit' ),
56 $reader->xpath( '//xliff:trans-unit' )
57 );
58
59 foreach ( $items as $item ) {
61 $source = $item->$element;
62
63 if ( !$source ) {
64 continue;
65 }
66
67 $key = (string)$item['id'];
68
69 /* In case there are tags inside the element, preserve
70 * them. */
71 $dom = new DOMDocument( '1.0' );
72 $dom->loadXML( $source->asXML() );
73 $value = self::getInnerXml( $dom->documentElement );
74
75 /* This might not be 100% according to the spec, but
76 * for now if there is explicit approved=no, mark it
77 * as fuzzy, but don't do that if the attribute is not
78 * set */
79 if ( (string)$source['state'] === 'needs-l10n' ) {
80 $value = TRANSLATE_FUZZY . $value;
81 }
82
83 // Strip CDATA if present
84 $value = preg_replace( '/<!\[CDATA\[(.*?)\]\]>/s', '\1', $value );
85
86 $messages[$key] = $value;
87 }
88
89 return [
90 'MESSAGES' => $mangler->mangleArray( $messages ),
91 ];
92 }
93
99 public function read( $code ) {
100 if ( !$this->exists( $code ) ) {
101 return false;
102 }
103
104 $filename = $this->group->getSourceFilePath( $code );
105 $input = file_get_contents( $filename );
106 if ( $input === false ) {
107 throw new MWException( "Unable to read file $filename." );
108 }
109
110 $element = $code === $this->group->getSourceLanguage() ? 'source' : 'target';
111
112 return $this->readFromVariable( $input, $element );
113 }
114
121 public static function getInnerXml( DOMElement $node ) {
122 $text = '';
123 foreach ( $node->childNodes as $child ) {
124 $text .= $child->ownerDocument->saveXML( $child );
125 }
126
127 return $text;
128 }
129
130 protected function writeReal( MessageCollection $collection ) {
131 $mangler = $this->group->getMangler();
132
133 $template = new DomDocument( '1.0' );
134 $template->preserveWhiteSpace = false;
135 $template->formatOutput = true;
136
137 // Try to use the definition file as template
138 $sourceLanguage = $this->group->getSourceLanguage();
139 $sourceFile = $this->group->getSourceFilePath( $sourceLanguage );
140 if ( file_exists( $sourceFile ) ) {
141 $template->load( $sourceFile );
142 } else {
143 // Else use standard template
144 $template->load( __DIR__ . '/../data/xliff-template.xml' );
145 }
146
147 $list = $template->getElementsByTagName( 'body' )->item( 0 );
148 $list->nodeValue = null;
149
151 foreach ( $collection as $key => $m ) {
152 $key = $mangler->unmangle( $key );
153
154 $value = $m->translation();
155 $value = str_replace( TRANSLATE_FUZZY, '', $value );
156
157 // @todo Support placeholder tags etc.
158 $source = $template->createDocumentFragment();
159 $source->appendXML( htmlspecialchars( $m->definition() ) );
160
161 $target = $template->createDocumentFragment();
162 $target->appendXML( htmlspecialchars( $value ) );
163
164 $sourceElement = $template->createElement( 'source' );
165 $sourceElement->appendChild( $source );
166
167 $targetElement = $template->createElement( 'target' );
168 $targetElement->appendChild( $target );
169 if ( $m->getProperty( 'status' ) === 'fuzzy' ) {
170 $targetElement->setAttribute( 'state', 'needs-l10n' );
171 }
172 if ( $m->getProperty( 'status' ) === 'proofread' ) {
173 $targetElement->setAttribute( 'state', 'signed-off' );
174 }
175
176 $transUnit = $template->createElement( 'trans-unit' );
177 $transUnit->setAttribute( 'id', $key );
178 $transUnit->appendChild( $sourceElement );
179 $transUnit->appendChild( $targetElement );
180
181 $list->appendChild( $transUnit );
182 }
183
184 $template->encoding = 'UTF-8';
185
186 return $template->saveXML();
187 }
188
189 public function supportsFuzzy() {
190 return 'yes';
191 }
192}
Core message collection class.
exists( $code=false)
Returns true if the file for this message group in a given language exists.
Definition SimpleFFS.php:76
Partial support for the Xliff translation format.
Definition XliffFFS.php:15
supportsFuzzy()
Query the capabilities of this FFS.
Definition XliffFFS.php:189
read( $code)
Definition XliffFFS.php:99
writeReal(MessageCollection $collection)
Definition XliffFFS.php:130
readFromVariable( $data, $element='target')
Definition XliffFFS.php:44
getFileExtensions()
Return the commonly used file extensions for these formats.
Definition XliffFFS.php:35
static getInnerXml(DOMElement $node)
Gets the html inside en element without the element itself.
Definition XliffFFS.php:121