Diff: STRATO-apps/wordpress_03/app/wp-includes/pomo/translations.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + /**
3 + * Class for a set of entries for translation and their associated headers
4 + *
5 + * @version $Id: translations.php 1157 2015-11-20 04:30:11Z dd32 $
6 + * @package pomo
7 + * @subpackage translations
8 + * @since 2.8.0
9 + */
10 +
11 + require_once __DIR__ . '/plural-forms.php';
12 + require_once __DIR__ . '/entry.php';
13 +
14 + if ( ! class_exists( 'Translations', false ) ) :
15 + /**
16 + * Translations class.
17 + *
18 + * @since 2.8.0
19 + */
20 + #[AllowDynamicProperties]
21 + class Translations {
22 + /**
23 + * List of translation entries.
24 + *
25 + * @since 2.8.0
26 + *
27 + * @var Translation_Entry[]
28 + */
29 + public $entries = array();
30 +
31 + /**
32 + * List of translation headers.
33 + *
34 + * @since 2.8.0
35 + *
36 + * @var array<string, string>
37 + */
38 + public $headers = array();
39 +
40 + /**
41 + * Adds an entry to the PO structure.
42 + *
43 + * @since 2.8.0
44 + *
45 + * @param array|Translation_Entry $entry
46 + * @return bool True on success, false if the entry doesn't have a key.
47 + */
48 + public function add_entry( $entry ) {
49 + if ( is_array( $entry ) ) {
50 + $entry = new Translation_Entry( $entry );
51 + }
52 + $key = $entry->key();
53 + if ( false === $key ) {
54 + return false;
55 + }
56 + $this->entries[ $key ] = &$entry;
57 + return true;
58 + }
59 +
60 + /**
61 + * Adds or merges an entry to the PO structure.
62 + *
63 + * @since 2.8.0
64 + *
65 + * @param array|Translation_Entry $entry
66 + * @return bool True on success, false if the entry doesn't have a key.
67 + */
68 + public function add_entry_or_merge( $entry ) {
69 + if ( is_array( $entry ) ) {
70 + $entry = new Translation_Entry( $entry );
71 + }
72 + $key = $entry->key();
73 + if ( false === $key ) {
74 + return false;
75 + }
76 + if ( isset( $this->entries[ $key ] ) ) {
77 + $this->entries[ $key ]->merge_with( $entry );
78 + } else {
79 + $this->entries[ $key ] = &$entry;
80 + }
81 + return true;
82 + }
83 +
84 + /**
85 + * Sets $header PO header to $value
86 + *
87 + * If the header already exists, it will be overwritten
88 + *
89 + * TODO: this should be out of this class, it is gettext specific
90 + *
91 + * @since 2.8.0
92 + *
93 + * @param string $header header name, without trailing :
94 + * @param string $value header value, without trailing \n
95 + */
96 + public function set_header( $header, $value ) {
97 + $this->headers[ $header ] = $value;
98 + }
99 +
100 + /**
101 + * Sets translation headers.
102 + *
103 + * @since 2.8.0
104 + *
105 + * @param array $headers Associative array of headers.
106 + */
107 + public function set_headers( $headers ) {
108 + foreach ( $headers as $header => $value ) {
109 + $this->set_header( $header, $value );
110 + }
111 + }
112 +
113 + /**
114 + * Returns a given translation header.
115 + *
116 + * @since 2.8.0
117 + *
118 + * @param string $header
119 + * @return string|false Header if it exists, false otherwise.
120 + */
121 + public function get_header( $header ) {
122 + return isset( $this->headers[ $header ] ) ? $this->headers[ $header ] : false;
123 + }
124 +
125 + /**
126 + * Returns a given translation entry.
127 + *
128 + * @since 2.8.0
129 + *
130 + * @param Translation_Entry $entry Translation entry.
131 + * @return Translation_Entry|false Translation entry if it exists, false otherwise.
132 + */
133 + public function translate_entry( &$entry ) {
134 + $key = $entry->key();
135 + return isset( $this->entries[ $key ] ) ? $this->entries[ $key ] : false;
136 + }
137 +
138 + /**
139 + * Translates a singular string.
140 + *
141 + * @since 2.8.0
142 + *
143 + * @param string $singular
144 + * @param string $context
145 + * @return string
146 + */
147 + public function translate( $singular, $context = null ) {
148 + $entry = new Translation_Entry(
149 + array(
150 + 'singular' => $singular,
151 + 'context' => $context,
152 + )
153 + );
154 + $translated = $this->translate_entry( $entry );
155 + return ( $translated && ! empty( $translated->translations ) ) ? $translated->translations[0] : $singular;
156 + }
157 +
158 + /**
159 + * Given the number of items, returns the 0-based index of the plural form to use
160 + *
161 + * Here, in the base Translations class, the common logic for English is implemented:
162 + * 0 if there is one element, 1 otherwise
163 + *
164 + * This function should be overridden by the subclasses. For example MO/PO can derive the logic
165 + * from their headers.
166 + *
167 + * @since 2.8.0
168 + *
169 + * @param int $count Number of items.
170 + * @return int Plural form to use.
171 + */
172 + public function select_plural_form( $count ) {
173 + return 1 === (int) $count ? 0 : 1;
174 + }
175 +
176 + /**
177 + * Returns the plural forms count.
178 + *
179 + * @since 2.8.0
180 + *
181 + * @return int Plural forms count.
182 + */
183 + public function get_plural_forms_count() {
184 + return 2;
185 + }
186 +
187 + /**
188 + * Translates a plural string.
189 + *
190 + * @since 2.8.0
191 + *
192 + * @param string $singular
193 + * @param string $plural
194 + * @param int $count
195 + * @param string $context
196 + * @return string
197 + */
198 + public function translate_plural( $singular, $plural, $count, $context = null ) {
199 + $entry = new Translation_Entry(
200 + array(
201 + 'singular' => $singular,
202 + 'plural' => $plural,
203 + 'context' => $context,
204 + )
205 + );
206 + $translated = $this->translate_entry( $entry );
207 + $index = $this->select_plural_form( $count );
208 + $total_plural_forms = $this->get_plural_forms_count();
209 + if ( $translated && 0 <= $index && $index < $total_plural_forms &&
210 + is_array( $translated->translations ) &&
211 + isset( $translated->translations[ $index ] ) ) {
212 + return $translated->translations[ $index ];
213 + } else {
214 + return 1 === (int) $count ? $singular : $plural;
215 + }
216 + }
217 +
218 + /**
219 + * Merges other translations into the current one.
220 + *
221 + * @since 2.8.0
222 + *
223 + * @param Translations $other Another Translation object, whose translations will be merged in this one (passed by reference).
224 + */
225 + public function merge_with( &$other ) {
226 + foreach ( $other->entries as $entry ) {
227 + $this->entries[ $entry->key() ] = $entry;
228 + }
229 + }
230 +
231 + /**
232 + * Merges originals with existing entries.
233 + *
234 + * @since 2.8.0
235 + *
236 + * @param Translations $other
237 + */
238 + public function merge_originals_with( &$other ) {
239 + foreach ( $other->entries as $entry ) {
240 + if ( ! isset( $this->entries[ $entry->key() ] ) ) {
241 + $this->entries[ $entry->key() ] = $entry;
242 + } else {
243 + $this->entries[ $entry->key() ]->merge_with( $entry );
244 + }
245 + }
246 + }
247 + }
248 +
249 + /**
250 + * Gettext_Translations class.
251 + *
252 + * @since 2.8.0
253 + */
254 + class Gettext_Translations extends Translations {
255 +
256 + /**
257 + * Number of plural forms.
258 + *
259 + * @var int
260 + *
261 + * @since 2.8.0
262 + */
263 + public $_nplurals;
264 +
265 + /**
266 + * Callback to retrieve the plural form.
267 + *
268 + * @var callable
269 + *
270 + * @since 2.8.0
271 + */
272 + public $_gettext_select_plural_form;
273 +
274 + /**
275 + * The gettext implementation of select_plural_form.
276 + *
277 + * It lives in this class, because there are more than one descendant, which will use it and
278 + * they can't share it effectively.
279 + *
280 + * @since 2.8.0
281 + *
282 + * @param int $count Plural forms count.
283 + * @return int Plural form to use.
284 + */
285 + public function gettext_select_plural_form( $count ) {
286 + if ( ! isset( $this->_gettext_select_plural_form ) || is_null( $this->_gettext_select_plural_form ) ) {
287 + list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) );
288 + $this->_nplurals = $nplurals;
289 + $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression );
290 + }
291 + return call_user_func( $this->_gettext_select_plural_form, $count );
292 + }
293 +
294 + /**
295 + * Returns the nplurals and plural forms expression from the Plural-Forms header.
296 + *
297 + * @since 2.8.0
298 + *
299 + * @param string $header
300 + * @return array{0: int, 1: string}
301 + */
302 + public function nplurals_and_expression_from_header( $header ) {
303 + if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) {
304 + $nplurals = (int) $matches[1];
305 + $expression = trim( $matches[2] );
306 + return array( $nplurals, $expression );
307 + } else {
308 + return array( 2, 'n != 1' );
309 + }
310 + }
311 +
312 + /**
313 + * Makes a function, which will return the right translation index, according to the
314 + * plural forms header.
315 + *
316 + * @since 2.8.0
317 + *
318 + * @param int $nplurals
319 + * @param string $expression
320 + * @return callable
321 + */
322 + public function make_plural_form_function( $nplurals, $expression ) {
323 + try {
324 + $handler = new Plural_Forms( rtrim( $expression, ';' ) );
325 + return array( $handler, 'get' );
326 + } catch ( Exception $e ) {
327 + // Fall back to default plural-form function.
328 + return $this->make_plural_form_function( 2, 'n != 1' );
329 + }
330 + }
331 +
332 + /**
333 + * Adds parentheses to the inner parts of ternary operators in
334 + * plural expressions, because PHP evaluates ternary operators from left to right
335 + *
336 + * @since 2.8.0
337 + * @deprecated 6.5.0 Use the Plural_Forms class instead.
338 + *
339 + * @see Plural_Forms
340 + *
341 + * @param string $expression the expression without parentheses
342 + * @return string the expression with parentheses added
343 + */
344 + public function parenthesize_plural_exression( $expression ) {
345 + $expression .= ';';
346 + $res = '';
347 + $depth = 0;
348 + for ( $i = 0; $i < strlen( $expression ); ++$i ) {
349 + $char = $expression[ $i ];
350 + switch ( $char ) {
351 + case '?':
352 + $res .= ' ? (';
353 + ++$depth;
354 + break;
355 + case ':':
356 + $res .= ') : (';
357 + break;
358 + case ';':
359 + $res .= str_repeat( ')', $depth ) . ';';
360 + $depth = 0;
361 + break;
362 + default:
363 + $res .= $char;
364 + }
365 + }
366 + return rtrim( $res, ';' );
367 + }
368 +
369 + /**
370 + * Prepare translation headers.
371 + *
372 + * @since 2.8.0
373 + *
374 + * @param string $translation
375 + * @return array<string, string> Translation headers
376 + */
377 + public function make_headers( $translation ) {
378 + $headers = array();
379 + // Sometimes \n's are used instead of real new lines.
380 + $translation = str_replace( '\n', "\n", $translation );
381 + $lines = explode( "\n", $translation );
382 + foreach ( $lines as $line ) {
383 + $parts = explode( ':', $line, 2 );
384 + if ( ! isset( $parts[1] ) ) {
385 + continue;
386 + }
387 + $headers[ trim( $parts[0] ) ] = trim( $parts[1] );
388 + }
389 + return $headers;
390 + }
391 +
392 + /**
393 + * Sets translation headers.
394 + *
395 + * @since 2.8.0
396 + *
397 + * @param string $header
398 + * @param string $value
399 + */
400 + public function set_header( $header, $value ) {
401 + parent::set_header( $header, $value );
402 + if ( 'Plural-Forms' === $header ) {
403 + list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) );
404 + $this->_nplurals = $nplurals;
405 + $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression );
406 + }
407 + }
408 + }
409 + endif;
410 +
411 + if ( ! class_exists( 'NOOP_Translations', false ) ) :
412 + /**
413 + * Provides the same interface as Translations, but doesn't do anything.
414 + *
415 + * @since 2.8.0
416 + */
417 + #[AllowDynamicProperties]
418 + class NOOP_Translations {
419 + /**
420 + * List of translation entries.
421 + *
422 + * @since 2.8.0
423 + *
424 + * @var Translation_Entry[]
425 + */
426 + public $entries = array();
427 +
428 + /**
429 + * List of translation headers.
430 + *
431 + * @since 2.8.0
432 + *
433 + * @var array<string, string>
434 + */
435 + public $headers = array();
436 +
437 + public function add_entry( $entry ) {
438 + return true;
439 + }
440 +
441 + /**
442 + * Sets a translation header.
443 + *
444 + * @since 2.8.0
445 + *
446 + * @param string $header
447 + * @param string $value
448 + */
449 + public function set_header( $header, $value ) {
450 + }
451 +
452 + /**
453 + * Sets translation headers.
454 + *
455 + * @since 2.8.0
456 + *
457 + * @param array $headers
458 + */
459 + public function set_headers( $headers ) {
460 + }
461 +
462 + /**
463 + * Returns a translation header.
464 + *
465 + * @since 2.8.0
466 + *
467 + * @param string $header
468 + * @return false
469 + */
470 + public function get_header( $header ) {
471 + return false;
472 + }
473 +
474 + /**
475 + * Returns a given translation entry.
476 + *
477 + * @since 2.8.0
478 + *
479 + * @param Translation_Entry $entry
480 + * @return false
481 + */
482 + public function translate_entry( &$entry ) {
483 + return false;
484 + }
485 +
486 + /**
487 + * Translates a singular string.
488 + *
489 + * @since 2.8.0
490 + *
491 + * @param string $singular
492 + * @param string $context
493 + */
494 + public function translate( $singular, $context = null ) {
495 + return $singular;
496 + }
497 +
498 + /**
499 + * Returns the plural form to use.
500 + *
501 + * @since 2.8.0
502 + *
503 + * @param int $count
504 + * @return int
505 + */
506 + public function select_plural_form( $count ) {
507 + return 1 === (int) $count ? 0 : 1;
508 + }
509 +
510 + /**
511 + * Returns the plural forms count.
512 + *
513 + * @since 2.8.0
514 + *
515 + * @return int
516 + */
517 + public function get_plural_forms_count() {
518 + return 2;
519 + }
520 +
521 + /**
522 + * Translates a plural string.
523 + *
524 + * @since 2.8.0
525 + *
526 + * @param string $singular
527 + * @param string $plural
528 + * @param int $count
529 + * @param string $context
530 + * @return string
531 + */
532 + public function translate_plural( $singular, $plural, $count, $context = null ) {
533 + return 1 === (int) $count ? $singular : $plural;
534 + }
535 +
536 + /**
537 + * Merges other translations into the current one.
538 + *
539 + * @since 2.8.0
540 + *
541 + * @param Translations $other
542 + */
543 + public function merge_with( &$other ) {
544 + }
545 + }
546 + endif;
547 +