1 <?php |
1 <?php |
2 /** |
2 /** |
3 * Class for a set of entries for translation and their associated headers |
3 * Class for a set of entries for translation and their associated headers |
4 * |
4 * |
5 * @version $Id: translations.php 718 2012-10-31 00:32:02Z nbachiyski $ |
5 * @version $Id: translations.php 1157 2015-11-20 04:30:11Z dd32 $ |
6 * @package pomo |
6 * @package pomo |
7 * @subpackage translations |
7 * @subpackage translations |
8 */ |
8 */ |
9 |
9 |
|
10 require_once dirname(__FILE__) . '/plural-forms.php'; |
10 require_once dirname(__FILE__) . '/entry.php'; |
11 require_once dirname(__FILE__) . '/entry.php'; |
11 |
12 |
12 if ( !class_exists( 'Translations' ) ): |
13 if ( ! class_exists( 'Translations', false ) ): |
13 class Translations { |
14 class Translations { |
14 var $entries = array(); |
15 var $entries = array(); |
15 var $headers = array(); |
16 var $headers = array(); |
16 |
17 |
17 /** |
18 /** |
18 * Add entry to the PO structure |
19 * Add entry to the PO structure |
19 * |
20 * |
20 * @param array|Translation_Entry &$entry |
21 * @param array|Translation_Entry $entry |
21 * @return bool true on success, false if the entry doesn't have a key |
22 * @return bool true on success, false if the entry doesn't have a key |
22 */ |
23 */ |
23 function add_entry($entry) { |
24 function add_entry($entry) { |
24 if (is_array($entry)) { |
25 if (is_array($entry)) { |
25 $entry = new Translation_Entry($entry); |
26 $entry = new Translation_Entry($entry); |
100 * Given the number of items, returns the 0-based index of the plural form to use |
101 * Given the number of items, returns the 0-based index of the plural form to use |
101 * |
102 * |
102 * Here, in the base Translations class, the common logic for English is implemented: |
103 * Here, in the base Translations class, the common logic for English is implemented: |
103 * 0 if there is one element, 1 otherwise |
104 * 0 if there is one element, 1 otherwise |
104 * |
105 * |
105 * This function should be overrided by the sub-classes. For example MO/PO can derive the logic |
106 * This function should be overridden by the sub-classes. For example MO/PO can derive the logic |
106 * from their headers. |
107 * from their headers. |
107 * |
108 * |
108 * @param integer $count number of items |
109 * @param integer $count number of items |
109 */ |
110 */ |
110 function select_plural_form($count) { |
111 function select_plural_form($count) { |
111 return 1 == $count? 0 : 1; |
112 return 1 == $count? 0 : 1; |
112 } |
113 } |
113 |
114 |
|
115 /** |
|
116 * @return int |
|
117 */ |
114 function get_plural_forms_count() { |
118 function get_plural_forms_count() { |
115 return 2; |
119 return 2; |
116 } |
120 } |
117 |
121 |
118 /** |
122 /** |
135 } |
139 } |
136 |
140 |
137 /** |
141 /** |
138 * Merge $other in the current object. |
142 * Merge $other in the current object. |
139 * |
143 * |
140 * @param Object &$other Another Translation object, whose translations will be merged in this one |
144 * @param Object $other Another Translation object, whose translations will be merged in this one (passed by reference). |
141 * @return void |
145 * @return void |
142 **/ |
146 **/ |
143 function merge_with(&$other) { |
147 function merge_with(&$other) { |
144 foreach( $other->entries as $entry ) { |
148 foreach( $other->entries as $entry ) { |
145 $this->entries[$entry->key()] = $entry; |
149 $this->entries[$entry->key()] = $entry; |
146 } |
150 } |
147 } |
151 } |
148 |
152 |
|
153 /** |
|
154 * @param object $other |
|
155 */ |
149 function merge_originals_with(&$other) { |
156 function merge_originals_with(&$other) { |
150 foreach( $other->entries as $entry ) { |
157 foreach( $other->entries as $entry ) { |
151 if ( !isset( $this->entries[$entry->key()] ) ) |
158 if ( !isset( $this->entries[$entry->key()] ) ) |
152 $this->entries[$entry->key()] = $entry; |
159 $this->entries[$entry->key()] = $entry; |
153 else |
160 else |
179 * @return array |
186 * @return array |
180 */ |
187 */ |
181 function nplurals_and_expression_from_header($header) { |
188 function nplurals_and_expression_from_header($header) { |
182 if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) { |
189 if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) { |
183 $nplurals = (int)$matches[1]; |
190 $nplurals = (int)$matches[1]; |
184 $expression = trim($this->parenthesize_plural_exression($matches[2])); |
191 $expression = trim( $matches[2] ); |
185 return array($nplurals, $expression); |
192 return array($nplurals, $expression); |
186 } else { |
193 } else { |
187 return array(2, 'n != 1'); |
194 return array(2, 'n != 1'); |
188 } |
195 } |
189 } |
196 } |
193 * plural forms header |
200 * plural forms header |
194 * @param int $nplurals |
201 * @param int $nplurals |
195 * @param string $expression |
202 * @param string $expression |
196 */ |
203 */ |
197 function make_plural_form_function($nplurals, $expression) { |
204 function make_plural_form_function($nplurals, $expression) { |
198 $expression = str_replace('n', '$n', $expression); |
205 try { |
199 $func_body = " |
206 $handler = new Plural_Forms( rtrim( $expression, ';' ) ); |
200 \$index = (int)($expression); |
207 return array( $handler, 'get' ); |
201 return (\$index < $nplurals)? \$index : $nplurals - 1;"; |
208 } catch ( Exception $e ) { |
202 return create_function('$n', $func_body); |
209 // Fall back to default plural-form function. |
|
210 return $this->make_plural_form_function( 2, 'n != 1' ); |
|
211 } |
203 } |
212 } |
204 |
213 |
205 /** |
214 /** |
206 * Adds parentheses to the inner parts of ternary operators in |
215 * Adds parentheses to the inner parts of ternary operators in |
207 * plural expressions, because PHP evaluates ternary oerators from left to right |
216 * plural expressions, because PHP evaluates ternary oerators from left to right |
276 |
285 |
277 function add_entry($entry) { |
286 function add_entry($entry) { |
278 return true; |
287 return true; |
279 } |
288 } |
280 |
289 |
|
290 /** |
|
291 * |
|
292 * @param string $header |
|
293 * @param string $value |
|
294 */ |
281 function set_header($header, $value) { |
295 function set_header($header, $value) { |
282 } |
296 } |
283 |
297 |
|
298 /** |
|
299 * |
|
300 * @param array $headers |
|
301 */ |
284 function set_headers($headers) { |
302 function set_headers($headers) { |
285 } |
303 } |
286 |
304 |
|
305 /** |
|
306 * @param string $header |
|
307 * @return false |
|
308 */ |
287 function get_header($header) { |
309 function get_header($header) { |
288 return false; |
310 return false; |
289 } |
311 } |
290 |
312 |
|
313 /** |
|
314 * @param Translation_Entry $entry |
|
315 * @return false |
|
316 */ |
291 function translate_entry(&$entry) { |
317 function translate_entry(&$entry) { |
292 return false; |
318 return false; |
293 } |
319 } |
294 |
320 |
295 /** |
321 /** |