1111
1212namespace Translation \SymfonyStorage \Dumper ;
1313
14- use Symfony \Component \Translation \Dumper \FileDumper ;
14+ use Nyholm \NSA ;
15+ use Symfony \Component \Translation \Dumper \XliffFileDumper ;
1516use Symfony \Component \Translation \MessageCatalogue ;
1617use Symfony \Component \Translation \Exception \InvalidArgumentException ;
18+ use Translation \SymfonyStorage \Dumper \Port \SymfonyPort ;
1719
1820/**
1921 * XliffFileDumper generates xliff files from a message catalogue.
20- * Mostly borrowed from Symfony.
22+ *
23+ * This class provides support for both SF2.7 and SF3.0+
2124 *
2225 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
2326 * @author Michel Salib <michelsalib@hotmail.com>
2427 */
25- final class XliffDumper extends FileDumper
28+ final class XliffDumper extends XliffFileDumper
2629{
30+ /**
31+ * @var SymfonyPort|null
32+ */
33+ private $ sfPort ;
34+
2735 /**
2836 * {@inheritdoc}
2937 */
@@ -41,188 +49,24 @@ public function formatCatalogue(MessageCatalogue $messages, $domain, array $opti
4149 }
4250
4351 if ('1.2 ' === $ xliffVersion ) {
44- return $ this ->dumpXliff1 ($ defaultLocale , $ messages , $ domain , $ options );
45- }
46- if ('2.0 ' === $ xliffVersion ) {
47- return $ this ->dumpXliff2 ($ defaultLocale , $ messages , $ domain , $ options );
48- }
49-
50- throw new InvalidArgumentException (
51- sprintf ('No support implemented for dumping XLIFF version "%s". ' , $ xliffVersion )
52- );
53- }
54-
55- /**
56- * Symfony 2.7 support.
57- *
58- * @param MessageCatalogue $messages
59- * @param string $domain
60- *
61- * @return string
62- */
63- protected function format (MessageCatalogue $ messages , $ domain )
64- {
65- return $ this ->dumpXliff2 (\Locale::getDefault (), $ messages , $ domain );
66- }
67-
68- /**
69- * {@inheritdoc}
70- */
71- protected function getExtension ()
72- {
73- return 'xlf ' ;
74- }
75-
76- private function dumpXliff1 ($ defaultLocale , MessageCatalogue $ messages , $ domain , array $ options = [])
77- {
78- $ toolInfo = ['tool-id ' => 'symfony ' , 'tool-name ' => 'Symfony ' ];
79- if (array_key_exists ('tool_info ' , $ options )) {
80- $ toolInfo = array_merge ($ toolInfo , $ options ['tool_info ' ]);
81- }
82-
83- $ dom = new \DOMDocument ('1.0 ' , 'utf-8 ' );
84- $ dom ->formatOutput = true ;
85-
86- $ xliff = $ dom ->appendChild ($ dom ->createElement ('xliff ' ));
87- $ xliff ->setAttribute ('version ' , '1.2 ' );
88- $ xliff ->setAttribute ('xmlns ' , 'urn:oasis:names:tc:xliff:document:1.2 ' );
89-
90- $ xliffFile = $ xliff ->appendChild ($ dom ->createElement ('file ' ));
91- $ xliffFile ->setAttribute ('source-language ' , str_replace ('_ ' , '- ' , $ defaultLocale ));
92- $ xliffFile ->setAttribute ('target-language ' , str_replace ('_ ' , '- ' , $ messages ->getLocale ()));
93- $ xliffFile ->setAttribute ('datatype ' , 'plaintext ' );
94- $ xliffFile ->setAttribute ('original ' , 'file.ext ' );
95-
96- $ xliffHead = $ xliffFile ->appendChild ($ dom ->createElement ('header ' ));
97- $ xliffTool = $ xliffHead ->appendChild ($ dom ->createElement ('tool ' ));
98- foreach ($ toolInfo as $ id => $ value ) {
99- $ xliffTool ->setAttribute ($ id , $ value );
100- }
101-
102- $ xliffBody = $ xliffFile ->appendChild ($ dom ->createElement ('body ' ));
103- foreach ($ messages ->all ($ domain ) as $ source => $ target ) {
104- $ translation = $ dom ->createElement ('trans-unit ' );
105-
106- $ translation ->setAttribute (
107- 'id ' ,
108- strtr (substr (base64_encode (hash ('sha256 ' , $ source , true )), 0 , 7 ), '/+ ' , '._ ' )
109- );
110- $ translation ->setAttribute ('resname ' , $ source );
111-
112- $ s = $ translation ->appendChild ($ dom ->createElement ('source ' ));
113- $ s ->appendChild ($ dom ->createTextNode ($ source ));
114-
115- // Does the target contain characters requiring a CDATA section?
116- $ text = 1 === preg_match ('/[&<>]/ ' , $ target ) ? $ dom ->createCDATASection ($ target ) : $ dom ->createTextNode (
117- $ target
118- );
119-
120- $ targetElement = $ dom ->createElement ('target ' );
121- $ metadata = $ messages ->getMetadata ($ source , $ domain );
122- if ($ this ->hasMetadataArrayInfo ('target-attributes ' , $ metadata )) {
123- foreach ($ metadata ['target-attributes ' ] as $ name => $ value ) {
124- $ targetElement ->setAttribute ($ name , $ value );
125- }
126- }
127- $ t = $ translation ->appendChild ($ targetElement );
128- $ t ->appendChild ($ text );
129-
130- if ($ this ->hasMetadataArrayInfo ('notes ' , $ metadata )) {
131- foreach ($ metadata ['notes ' ] as $ note ) {
132- if (!isset ($ note ['content ' ])) {
133- continue ;
134- }
135-
136- $ n = $ translation ->appendChild ($ dom ->createElement ('note ' ));
137- $ n ->appendChild ($ dom ->createTextNode ($ note ['content ' ]));
138-
139- if (isset ($ note ['priority ' ])) {
140- $ n ->setAttribute ('priority ' , $ note ['priority ' ]);
141- }
142-
143- if (isset ($ note ['from ' ])) {
144- $ n ->setAttribute ('from ' , $ note ['from ' ]);
145- }
146- }
52+ if (method_exists ($ this , 'dumpXliff1 ' )) {
53+ return NSA ::invokeMethod ($ this , 'dumpXliff1 ' , $ defaultLocale , $ messages , $ domain , $ options );
54+ } else {
55+ // Symfony 2.7
56+ return $ this ->format ($ messages , $ domain );
14757 }
148-
149- $ xliffBody ->appendChild ($ translation );
15058 }
15159
152- return $ dom ->saveXML ();
153- }
154-
155- private function dumpXliff2 ($ defaultLocale , MessageCatalogue $ messages , $ domain , array $ options = [])
156- {
157- $ dom = new \DOMDocument ('1.0 ' , 'utf-8 ' );
158- $ dom ->formatOutput = true ;
159-
160- $ xliff = $ dom ->appendChild ($ dom ->createElement ('xliff ' ));
161- $ xliff ->setAttribute ('xmlns ' , 'urn:oasis:names:tc:xliff:document:2.0 ' );
162- $ xliff ->setAttribute ('version ' , '2.0 ' );
163- $ xliff ->setAttribute ('srcLang ' , str_replace ('_ ' , '- ' , $ defaultLocale ));
164- $ xliff ->setAttribute ('trgLang ' , str_replace ('_ ' , '- ' , $ messages ->getLocale ()));
165-
166- $ xliffFile = $ xliff ->appendChild ($ dom ->createElement ('file ' ));
167- $ xliffFile ->setAttribute ('id ' , $ domain .'. ' .$ messages ->getLocale ());
168-
169- foreach ($ messages ->all ($ domain ) as $ source => $ target ) {
170- $ translation = $ dom ->createElement ('unit ' );
171- $ translation ->setAttribute ('id ' , strtr (substr (base64_encode (hash ('sha256 ' , $ source , true )), 0 , 7 ), '/+ ' , '._ ' ));
172- $ metadata = $ messages ->getMetadata ($ source , $ domain );
173-
174- // Add notes section
175- if ($ this ->hasMetadataArrayInfo ('notes ' , $ metadata )) {
176- $ notesElement = $ dom ->createElement ('notes ' );
177- foreach ($ metadata ['notes ' ] as $ note ) {
178- $ n = $ dom ->createElement ('note ' );
179- $ n ->appendChild ($ dom ->createTextNode (isset ($ note ['content ' ]) ? $ note ['content ' ] : '' ));
180- unset($ note ['content ' ]);
181-
182- foreach ($ note as $ name => $ value ) {
183- $ n ->setAttribute ($ name , $ value );
184- }
185- $ notesElement ->appendChild ($ n );
186- }
187- $ translation ->appendChild ($ notesElement );
188- }
189-
190- $ segment = $ translation ->appendChild ($ dom ->createElement ('segment ' ));
191-
192- $ s = $ segment ->appendChild ($ dom ->createElement ('source ' ));
193- $ s ->appendChild ($ dom ->createTextNode ($ source ));
194-
195- // Does the target contain characters requiring a CDATA section?
196- $ text = 1 === preg_match ('/[&<>]/ ' , $ target ) ? $ dom ->createCDATASection ($ target ) : $ dom ->createTextNode (
197- $ target
198- );
199-
200- $ targetElement = $ dom ->createElement ('target ' );
201- if ($ this ->hasMetadataArrayInfo ('target-attributes ' , $ metadata )) {
202- foreach ($ metadata ['target-attributes ' ] as $ name => $ value ) {
203- $ targetElement ->setAttribute ($ name , $ value );
204- }
60+ if ('2.0 ' === $ xliffVersion ) {
61+ if (null === $ this ->sfPort ) {
62+ $ this ->sfPort = new SymfonyPort ();
20563 }
20664
207- $ t = $ segment ->appendChild ($ targetElement );
208- $ t ->appendChild ($ text );
209-
210- $ xliffFile ->appendChild ($ translation );
65+ return $ this ->sfPort ->dumpXliff2 ($ defaultLocale , $ messages , $ domain , $ options );
21166 }
21267
213- return $ dom ->saveXML ();
214- }
215-
216- /**
217- * @param string $key
218- * @param array|null $metadata
219- *
220- * @return bool
221- */
222- private function hasMetadataArrayInfo ($ key , $ metadata = null )
223- {
224- return null !== $ metadata &&
225- array_key_exists ($ key , $ metadata ) &&
226- ($ metadata [$ key ] instanceof \Traversable || is_array ($ metadata [$ key ]));
68+ throw new InvalidArgumentException (
69+ sprintf ('No support implemented for dumping XLIFF version "%s". ' , $ xliffVersion )
70+ );
22771 }
22872}
0 commit comments