32 if ( !$fh ) return false; |
32 if ( !$fh ) return false; |
33 $res = $this->export_to_file_handle( $fh ); |
33 $res = $this->export_to_file_handle( $fh ); |
34 fclose($fh); |
34 fclose($fh); |
35 return $res; |
35 return $res; |
36 } |
36 } |
37 |
37 |
38 function export() { |
38 function export() { |
39 $tmp_fh = fopen("php://temp", 'r+'); |
39 $tmp_fh = fopen("php://temp", 'r+'); |
40 if ( !$tmp_fh ) return false; |
40 if ( !$tmp_fh ) return false; |
41 $this->export_to_file_handle( $tmp_fh ); |
41 $this->export_to_file_handle( $tmp_fh ); |
42 rewind( $tmp_fh ); |
42 rewind( $tmp_fh ); |
43 return stream_get_contents( $tmp_fh ); |
43 return stream_get_contents( $tmp_fh ); |
44 } |
44 } |
45 |
45 |
|
46 function is_entry_good_for_export( $entry ) { |
|
47 if ( empty( $entry->translations ) ) { |
|
48 return false; |
|
49 } |
|
50 |
|
51 if ( !array_filter( $entry->translations ) ) { |
|
52 return false; |
|
53 } |
|
54 |
|
55 return true; |
|
56 } |
|
57 |
46 function export_to_file_handle($fh) { |
58 function export_to_file_handle($fh) { |
47 $entries = array_filter($this->entries, create_function('$e', 'return !empty($e->translations);')); |
59 $entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) ); |
48 ksort($entries); |
60 ksort($entries); |
49 $magic = 0x950412de; |
61 $magic = 0x950412de; |
50 $revision = 0; |
62 $revision = 0; |
51 $total = count($entries) + 1; // all the headers are one entry |
63 $total = count($entries) + 1; // all the headers are one entry |
52 $originals_lenghts_addr = 28; |
64 $originals_lenghts_addr = 28; |
55 $hash_addr = $translations_lenghts_addr + 8 * $total; |
67 $hash_addr = $translations_lenghts_addr + 8 * $total; |
56 $current_addr = $hash_addr; |
68 $current_addr = $hash_addr; |
57 fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr, |
69 fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr, |
58 $translations_lenghts_addr, $size_of_hash, $hash_addr)); |
70 $translations_lenghts_addr, $size_of_hash, $hash_addr)); |
59 fseek($fh, $originals_lenghts_addr); |
71 fseek($fh, $originals_lenghts_addr); |
60 |
72 |
61 // headers' msgid is an empty string |
73 // headers' msgid is an empty string |
62 fwrite($fh, pack('VV', 0, $current_addr)); |
74 fwrite($fh, pack('VV', 0, $current_addr)); |
63 $current_addr++; |
75 $current_addr++; |
64 $originals_table = chr(0); |
76 $originals_table = chr(0); |
65 |
77 |
67 $originals_table .= $this->export_original($entry) . chr(0); |
79 $originals_table .= $this->export_original($entry) . chr(0); |
68 $length = strlen($this->export_original($entry)); |
80 $length = strlen($this->export_original($entry)); |
69 fwrite($fh, pack('VV', $length, $current_addr)); |
81 fwrite($fh, pack('VV', $length, $current_addr)); |
70 $current_addr += $length + 1; // account for the NULL byte after |
82 $current_addr += $length + 1; // account for the NULL byte after |
71 } |
83 } |
72 |
84 |
73 $exported_headers = $this->export_headers(); |
85 $exported_headers = $this->export_headers(); |
74 fwrite($fh, pack('VV', strlen($exported_headers), $current_addr)); |
86 fwrite($fh, pack('VV', strlen($exported_headers), $current_addr)); |
75 $current_addr += strlen($exported_headers) + 1; |
87 $current_addr += strlen($exported_headers) + 1; |
76 $translations_table = $exported_headers . chr(0); |
88 $translations_table = $exported_headers . chr(0); |
77 |
89 |
78 foreach($entries as $entry) { |
90 foreach($entries as $entry) { |
79 $translations_table .= $this->export_translations($entry) . chr(0); |
91 $translations_table .= $this->export_translations($entry) . chr(0); |
80 $length = strlen($this->export_translations($entry)); |
92 $length = strlen($this->export_translations($entry)); |
81 fwrite($fh, pack('VV', $length, $current_addr)); |
93 fwrite($fh, pack('VV', $length, $current_addr)); |
82 $current_addr += $length + 1; |
94 $current_addr += $length + 1; |
83 } |
95 } |
84 |
96 |
85 fwrite($fh, $originals_table); |
97 fwrite($fh, $originals_table); |
86 fwrite($fh, $translations_table); |
98 fwrite($fh, $translations_table); |
87 return true; |
99 return true; |
88 } |
100 } |
89 |
101 |
90 function export_original($entry) { |
102 function export_original($entry) { |
91 //TODO: warnings for control characters |
103 //TODO: warnings for control characters |
92 $exported = $entry->singular; |
104 $exported = $entry->singular; |
93 if ($entry->is_plural) $exported .= chr(0).$entry->plural; |
105 if ($entry->is_plural) $exported .= chr(0).$entry->plural; |
94 if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported; |
106 if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported; |
95 return $exported; |
107 return $exported; |
96 } |
108 } |
97 |
109 |
98 function export_translations($entry) { |
110 function export_translations($entry) { |
99 //TODO: warnings for control characters |
111 //TODO: warnings for control characters |
100 return implode(chr(0), $entry->translations); |
112 return implode(chr(0), $entry->translations); |
101 } |
113 } |
102 |
114 |
103 function export_headers() { |
115 function export_headers() { |
104 $exported = ''; |
116 $exported = ''; |
105 foreach($this->headers as $header => $value) { |
117 foreach($this->headers as $header => $value) { |
106 $exported.= "$header: $value\n"; |
118 $exported.= "$header: $value\n"; |
107 } |
119 } |
193 |
205 |
194 $original = $reader->substr( $strings, $o['pos'], $o['length'] ); |
206 $original = $reader->substr( $strings, $o['pos'], $o['length'] ); |
195 $translation = $reader->substr( $strings, $t['pos'], $t['length'] ); |
207 $translation = $reader->substr( $strings, $t['pos'], $t['length'] ); |
196 |
208 |
197 if ('' === $original) { |
209 if ('' === $original) { |
198 $headers = $this->make_headers($translation); |
210 $this->set_headers($this->make_headers($translation)); |
199 $this->set_headers($headers); |
|
200 } else { |
211 } else { |
201 $entry = &$this->make_entry($original, $translation); |
212 $entry = &$this->make_entry($original, $translation); |
202 $this->entries[$entry->key()] = &$entry; |
213 $this->entries[$entry->key()] = &$entry; |
203 } |
214 } |
204 } |
215 } |