|
1 <?php |
|
2 /** |
|
3 * I18N: WP_Translations class. |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage I18N |
|
7 * @since 6.5.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Class WP_Translations. |
|
12 * |
|
13 * @since 6.5.0 |
|
14 * |
|
15 * @property-read array<string, string> $headers |
|
16 * @property-read array<string, string[]> $entries |
|
17 */ |
|
18 class WP_Translations { |
|
19 /** |
|
20 * Text domain. |
|
21 * |
|
22 * @since 6.5.0 |
|
23 * @var string |
|
24 */ |
|
25 protected $textdomain = 'default'; |
|
26 |
|
27 /** |
|
28 * Translation controller instance. |
|
29 * |
|
30 * @since 6.5.0 |
|
31 * @var WP_Translation_Controller |
|
32 */ |
|
33 protected $controller; |
|
34 |
|
35 /** |
|
36 * Constructor. |
|
37 * |
|
38 * @since 6.5.0 |
|
39 * |
|
40 * @param WP_Translation_Controller $controller I18N controller. |
|
41 * @param string $textdomain Optional. Text domain. Default 'default'. |
|
42 */ |
|
43 public function __construct( WP_Translation_Controller $controller, string $textdomain = 'default' ) { |
|
44 $this->controller = $controller; |
|
45 $this->textdomain = $textdomain; |
|
46 } |
|
47 |
|
48 /** |
|
49 * Magic getter for backward compatibility. |
|
50 * |
|
51 * @since 6.5.0 |
|
52 * |
|
53 * @param string $name Property name. |
|
54 * @return mixed |
|
55 */ |
|
56 public function __get( string $name ) { |
|
57 if ( 'entries' === $name ) { |
|
58 $entries = $this->controller->get_entries( $this->textdomain ); |
|
59 |
|
60 $result = array(); |
|
61 |
|
62 foreach ( $entries as $original => $translations ) { |
|
63 $result[] = $this->make_entry( $original, $translations ); |
|
64 } |
|
65 |
|
66 return $result; |
|
67 } |
|
68 |
|
69 if ( 'headers' === $name ) { |
|
70 return $this->controller->get_headers( $this->textdomain ); |
|
71 } |
|
72 |
|
73 return null; |
|
74 } |
|
75 |
|
76 /** |
|
77 * Builds a Translation_Entry from original string and translation strings. |
|
78 * |
|
79 * @see MO::make_entry() |
|
80 * |
|
81 * @since 6.5.0 |
|
82 * |
|
83 * @param string $original Original string to translate from MO file. Might contain |
|
84 * 0x04 as context separator or 0x00 as singular/plural separator. |
|
85 * @param string $translations Translation strings from MO file. |
|
86 * @return Translation_Entry Entry instance. |
|
87 */ |
|
88 private function make_entry( $original, $translations ): Translation_Entry { |
|
89 $entry = new Translation_Entry(); |
|
90 |
|
91 // Look for context, separated by \4. |
|
92 $parts = explode( "\4", $original ); |
|
93 if ( isset( $parts[1] ) ) { |
|
94 $original = $parts[1]; |
|
95 $entry->context = $parts[0]; |
|
96 } |
|
97 |
|
98 $entry->singular = $original; |
|
99 $entry->translations = explode( "\0", $translations ); |
|
100 $entry->is_plural = count( $entry->translations ) > 1; |
|
101 |
|
102 return $entry; |
|
103 } |
|
104 |
|
105 /** |
|
106 * Translates a plural string. |
|
107 * |
|
108 * @since 6.5.0 |
|
109 * |
|
110 * @param string|null $singular Singular string. |
|
111 * @param string|null $plural Plural string. |
|
112 * @param int|float $count Count. Should be an integer, but some plugins pass floats. |
|
113 * @param string|null $context Context. |
|
114 * @return string|null Translation if it exists, or the unchanged singular string. |
|
115 */ |
|
116 public function translate_plural( $singular, $plural, $count = 1, $context = '' ) { |
|
117 if ( null === $singular || null === $plural ) { |
|
118 return $singular; |
|
119 } |
|
120 |
|
121 $translation = $this->controller->translate_plural( array( $singular, $plural ), (int) $count, (string) $context, $this->textdomain ); |
|
122 if ( false !== $translation ) { |
|
123 return $translation; |
|
124 } |
|
125 |
|
126 // Fall back to the original with English grammar rules. |
|
127 return ( 1 === $count ? $singular : $plural ); |
|
128 } |
|
129 |
|
130 /** |
|
131 * Translates a singular string. |
|
132 * |
|
133 * @since 6.5.0 |
|
134 * |
|
135 * @param string|null $singular Singular string. |
|
136 * @param string|null $context Context. |
|
137 * @return string|null Translation if it exists, or the unchanged singular string |
|
138 */ |
|
139 public function translate( $singular, $context = '' ) { |
|
140 if ( null === $singular ) { |
|
141 return null; |
|
142 } |
|
143 |
|
144 $translation = $this->controller->translate( $singular, (string) $context, $this->textdomain ); |
|
145 if ( false !== $translation ) { |
|
146 return $translation; |
|
147 } |
|
148 |
|
149 // Fall back to the original. |
|
150 return $singular; |
|
151 } |
|
152 } |