PluginProbe
Polylang / 2.0.12
Polylang v2.0.12
3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 All 234 releases
← All changes | modules/wpml/wpml-config.php +96 -134 3.0.3 → 2.0.12 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 /**
7 4 * Reads and interprets the file wpml-config.xml
8 5 * See http://wpml.org/documentation/support/language-configuration-files/
@@ -10,23 +7,12 @@
10 7 *
11 8 * @since 1.0
12 9 */
13 10 class PLL_WPML_Config {
14 - /**
15 - * Singleton instance
16 - *
17 - * @var PLL_WPML_Config
18 - */
19 - protected static $instance;
11 + static protected $instance; // For singleton
12 + protected $xmls, $options;
20 13
21 14 /**
22 - * The content of all read xml files.
23 - *
24 - * @var SimpleXMLElement[]
25 - */
26 - protected $xmls;
27 -
28 - /**
29 15 * Constructor
30 16 *
31 17 * @since 1.0
32 18 */
@@ -42,9 +28,9 @@
42 28 * @since 1.7
43 29 *
44 30 * @return object
45 31 */
46 - public static function instance() {
32 + static public function instance() {
47 33 if ( empty( self::$instance ) ) {
48 34 self::$instance = new self();
49 35 }
50 36 return self::$instance;
@@ -53,18 +39,26 @@
53 39 /**
54 40 * Finds the wpml-config.xml files to parse and setup filters
55 41 *
56 42 * @since 1.0
57 - *
58 - * @return void
59 43 */
60 44 public function init() {
61 45 $this->xmls = array();
62 46
47 + // Theme
48 + if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
49 + $this->xmls[ get_template() ] = $xml;
50 + }
51 +
52 + // Child theme
53 + if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
54 + $this->xmls[ get_stylesheet() ] = $xml;
55 + }
56 +
63 57 // Plugins
64 58 // Don't forget sitewide active plugins thanks to Reactorshop http://wordpress.org/support/topic/polylang-and-yoast-seo-plugin/page/2?replies=38#post-4801829
65 59 $plugins = ( is_multisite() && $sitewide_plugins = get_site_option( 'active_sitewide_plugins' ) ) && is_array( $sitewide_plugins ) ? array_keys( $sitewide_plugins ) : array();
66 - $plugins = array_merge( $plugins, get_option( 'active_plugins', array() ) );
60 + $plugins = array_merge( $plugins, get_option( 'active_plugins' ) );
67 61
68 62 foreach ( $plugins as $plugin ) {
69 63 if ( file_exists( $file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
70 64 $this->xmls[ dirname( $plugin ) ] = $xml;
@@ -70,18 +64,8 @@
70 64 $this->xmls[ dirname( $plugin ) ] = $xml;
71 65 }
72 66 }
73 67
74 - // Theme
75 - if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
76 - $this->xmls[ get_template() ] = $xml;
77 - }
78 -
79 - // Child theme
80 - if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
81 - $this->xmls[ get_stylesheet() ] = $xml;
82 - }
83 -
84 68 // Custom
85 69 if ( file_exists( $file = PLL_LOCAL_DIR . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
86 70 $this->xmls['Polylang'] = $xml;
87 71 }
@@ -86,32 +70,21 @@
86 70 $this->xmls['Polylang'] = $xml;
87 71 }
88 72
89 73 if ( ! empty( $this->xmls ) ) {
90 - add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 20, 2 );
91 - add_filter( 'pll_copy_term_metas', array( $this, 'copy_term_metas' ), 20, 2 );
74 + add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 2 );
92 75 add_filter( 'pll_get_post_types', array( $this, 'translate_types' ), 10, 2 );
93 76 add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
94 77
95 78 foreach ( $this->xmls as $context => $xml ) {
96 - $keys = $xml->xpath( 'admin-texts/key' );
97 - if ( is_array( $keys ) ) {
98 - foreach ( $keys as $key ) {
99 - $attributes = $key->attributes();
100 - $name = (string) $attributes['name'];
101 -
102 - if ( false !== strpos( $name, '*' ) ) {
103 - $pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
104 - $names = preg_grep( $pattern, array_keys( wp_load_alloptions() ) );
105 -
106 - if ( is_array( $names ) ) {
107 - foreach ( $names as $_name ) {
108 - $this->register_or_translate_option( $context, $_name, $key );
109 - }
110 - }
111 - } else {
112 - $this->register_or_translate_option( $context, $name, $key );
113 - }
79 + foreach ( $xml->xpath( 'admin-texts/key' ) as $key ) {
80 + $attributes = $key->attributes();
81 + $name = (string) $attributes['name'];
82 + if ( PLL() instanceof PLL_Frontend ) {
83 + $this->options[ $name ] = $key;
84 + add_filter( 'option_' . $name, array( $this, 'translate_strings' ) );
85 + } else {
86 + $this->register_string_recursive( $context, get_option( $name ), $key );
114 87 }
115 88 }
116 89 }
117 90 }
@@ -117,27 +90,24 @@
117 90 }
118 91 }
119 92
120 93 /**
121 - * Adds custom fields to the list of metas to copy when creating a new translation.
94 + * Adds custom fields to the list of metas to copy when creating a new translation
122 95 *
123 96 * @since 1.0
124 97 *
125 - * @param string[] $metas The list of custom fields to copy or synchronize.
126 - * @param bool $sync True for sync, false for copy.
127 - * @return string[] The list of custom fields to copy or synchronize.
98 + * @param array $metas the list of custom fields to copy or synchronize
99 + * @param bool $sync true for sync, false for copy
100 + * @return array the list of custom fields to copy or synchronize
128 101 */
129 102 public function copy_post_metas( $metas, $sync ) {
130 103 foreach ( $this->xmls as $xml ) {
131 - $cfs = $xml->xpath( 'custom-fields/custom-field' );
132 - if ( is_array( $cfs ) ) {
133 - foreach ( $cfs as $cf ) {
134 - $attributes = $cf->attributes();
135 - if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
136 - $metas[] = (string) $cf;
137 - } else {
138 - $metas = array_diff( $metas, array( (string) $cf ) );
139 - }
104 + foreach ( $xml->xpath( 'custom-fields/custom-field' ) as $cf ) {
105 + $attributes = $cf->attributes();
106 + if ( 'copy' == $attributes['action'] || ( ! $sync && 'translate' == $attributes['action'] ) ) {
107 + $metas[] = (string) $cf;
108 + } else {
109 + $metas = array_diff( $metas, array( (string) $cf ) );
140 110 }
141 111 }
142 112 }
143 113 return $metas;
@@ -143,120 +113,112 @@
143 113 return $metas;
144 114 }
145 115
146 116 /**
147 - * Adds term metas to the list of metas to copy when creating a new translation.
117 + * Language and translation management for custom post types
148 118 *
149 - * @since 2.6
119 + * @since 1.0
150 120 *
151 - * @param string[] $metas The list of term metas to copy or synchronize.
152 - * @param bool $sync True for sync, false for copy.
153 - * @return string[] The list of term metas to copy or synchronize.
121 + * @param array $types list of post type names for which Polylang manages language and translations
122 + * @param bool $hide true when displaying the list in Polylang settings
123 + * @return array list of post type names for which Polylang manages language and translations
154 124 */
155 - public function copy_term_metas( $metas, $sync ) {
125 + public function translate_types( $types, $hide ) {
156 126 foreach ( $this->xmls as $xml ) {
157 - $cfs = $xml->xpath( 'custom-term-fields/custom-term-field' );
158 - if ( is_array( $cfs ) ) {
159 - foreach ( $cfs as $cf ) {
160 - $attributes = $cf->attributes();
161 - if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
162 - $metas[] = (string) $cf;
163 - } else {
164 - $metas = array_diff( $metas, array( (string) $cf ) );
165 - }
127 + foreach ( $xml->xpath( 'custom-types/custom-type' ) as $pt ) {
128 + $attributes = $pt->attributes();
129 + if ( 1 == $attributes['translate'] && ! $hide ) {
130 + $types[ (string) $pt ] = (string) $pt;
131 + } else {
132 + unset( $types[ (string) $pt ] ); // The theme/plugin author decided what to do with the post type so don't allow the user to change this
166 133 }
167 134 }
168 135 }
169 - return $metas;
136 + return $types;
170 137 }
171 138
172 139 /**
173 - * Language and translation management for custom post types.
140 + * Language and translation management for custom taxonomies
174 141 *
175 142 * @since 1.0
176 143 *
177 - * @param string[] $types The list of post type names for which Polylang manages language and translations.
178 - * @param bool $hide True when displaying the list in Polylang settings.
179 - * @return string[] The list of post type names for which Polylang manages language and translations.
144 + * @param array $taxonomies list of taxonomy names for which Polylang manages language and translations
145 + * @param bool $hide true when displaying the list in Polylang settings
146 + * @return array list of taxonomy names for which Polylang manages language and translations
180 147 */
181 - public function translate_types( $types, $hide ) {
148 + public function translate_taxonomies( $taxonomies, $hide ) {
182 149 foreach ( $this->xmls as $xml ) {
183 - $pts = $xml->xpath( 'custom-types/custom-type' );
184 - if ( is_array( $pts ) ) {
185 - foreach ( $pts as $pt ) {
186 - $attributes = $pt->attributes();
187 - if ( 1 == $attributes['translate'] && ! $hide ) {
188 - $types[ (string) $pt ] = (string) $pt;
189 - } else {
190 - unset( $types[ (string) $pt ] ); // The theme/plugin author decided what to do with the post type so don't allow the user to change this
191 - }
150 + foreach ( $xml->xpath( 'taxonomies/taxonomy' ) as $tax ) {
151 + $attributes = $tax->attributes();
152 + if ( 1 == $attributes['translate'] && ! $hide ) {
153 + $taxonomies[ (string) $tax ] = (string) $tax;
154 + } else {
155 + unset( $taxonomies[ (string) $tax ] ); // the theme/plugin author decided what to do with the taxonomy so don't allow the user to change this
192 156 }
193 157 }
194 158 }
195 - return $types;
159 + return $taxonomies;
196 160 }
197 161
198 162 /**
199 - * Language and translation management for custom taxonomies.
163 + * Translates the strings for an option
200 164 *
201 165 * @since 1.0
202 166 *
203 - * @param string[] $taxonomies The list of taxonomy names for which Polylang manages language and translations.
204 - * @param bool $hide True when displaying the list in Polylang settings.
205 - * @return string[] The list of taxonomy names for which Polylang manages language and translations.
167 + * @param array|string either a string to translate or a list of strings to translate
168 + * @return array|string translated string(s)
206 169 */
207 - public function translate_taxonomies( $taxonomies, $hide ) {
208 - foreach ( $this->xmls as $xml ) {
209 - $taxos = $xml->xpath( 'taxonomies/taxonomy' );
210 - if ( is_array( $taxos ) ) {
211 - foreach ( $taxos as $tax ) {
212 - $attributes = $tax->attributes();
213 - if ( 1 == $attributes['translate'] && ! $hide ) {
214 - $taxonomies[ (string) $tax ] = (string) $tax;
215 - } else {
216 - unset( $taxonomies[ (string) $tax ] ); // the theme/plugin author decided what to do with the taxonomy so don't allow the user to change this
217 - }
218 - }
219 - }
220 - }
221 - return $taxonomies;
170 + public function translate_strings( $value ) {
171 + $option = substr( current_filter(), 7 );
172 + return $this->translate_strings_recursive( $value, $this->options[ $option ] );
222 173 }
223 174
224 175 /**
225 - * Registers or translates the strings for an option
176 + * Recursively registers strings for a serialized option
226 177 *
227 - * @since 2.8
178 + * @since 1.0
228 179 *
229 - * @param string $context The group in which the strings will be registered.
230 - * @param string $name Option name.
231 - * @param object $key XML node.
232 - * @return void
180 + * @param string $context the group in which the strings will be registered
181 + * @param array $options
182 + * @param object $key XML node
233 183 */
234 - protected function register_or_translate_option( $context, $name, $key ) {
235 - $option_keys = $this->xml_to_array( $key );
236 - new PLL_Translate_Option( $name, reset( $option_keys ), array( 'context' => $context ) );
184 + protected function register_string_recursive( $context, $options, $key ) {
185 + $children = $key->children();
186 + if ( count( $children ) ) {
187 + foreach ( $children as $child ) {
188 + $attributes = $child->attributes();
189 + $name = (string) $attributes['name'];
190 + if ( isset( $options[ $name ] ) ) {
191 + $this->register_string_recursive( $context, $options[ $name ], $child );
192 + }
193 + }
194 + } else {
195 + $attributes = $key->attributes();
196 + pll_register_string( (string) $attributes['name'], $options, $context );
197 + }
237 198 }
238 199
239 200 /**
240 - * Recursively transforms xml nodes to an array, ready for PLL_Translate_Option.
201 + * Recursively translates strings for a serialized option
241 202 *
242 - * @since 2.9
203 + * @since 1.0
243 204 *
244 - * @param object $key XML node.
245 - * @param array $arr Array of option keys to translate.
246 - * @return array
205 + * @param array|string $values either a string to translate or a list of strings to translate
206 + * @param object $key XML node
207 + * @return array|string translated string(s)
247 208 */
248 - protected function xml_to_array( $key, &$arr = array() ) {
249 - $attributes = $key->attributes();
250 - $name = (string) $attributes['name'];
209 + protected function translate_strings_recursive( $values, $key ) {
251 210 $children = $key->children();
252 -
253 211 if ( count( $children ) ) {
254 212 foreach ( $children as $child ) {
255 - $arr[ $name ] = $this->xml_to_array( $child, $arr[ $name ] );
213 + $attributes = $child->attributes();
214 + $name = (string) $attributes['name'];
215 + if ( isset( $values[ $name ] ) ) {
216 + $values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
217 + }
256 218 }
257 219 } else {
258 - $arr[ $name ] = true; // Multiline as in WPML.
220 + $values = pll__( $values );
259 221 }
260 - return $arr;
222 + return $values;
261 223 }
262 224 }