PluginProbe
Polylang / 2.6.2
Polylang v2.6.2
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 3.0.3 All 233 releases
polylang / modules / wpml / wpml-config.php

wpml-config.php in Polylang 2.6.2, at modules/wpml/wpml-config.php

296 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Reads and interprets the file wpml-config.xml
5 * See http://wpml.org/documentation/support/language-configuration-files/
6 * The language switcher configuration is not interpreted
7 *
8 * @since 1.0
9 */
10 class PLL_WPML_Config {
11 protected static $instance; // For singleton
12 protected $xmls, $options;
13
14 /**
15 * Constructor
16 *
17 * @since 1.0
18 */
19 public function __construct() {
20 if ( extension_loaded( 'simplexml' ) ) {
21 $this->init();
22 }
23 }
24
25 /**
26 * Access to the single instance of the class
27 *
28 * @since 1.7
29 *
30 * @return object
31 */
32 public static function instance() {
33 if ( empty( self::$instance ) ) {
34 self::$instance = new self();
35 }
36 return self::$instance;
37 }
38
39 /**
40 * Finds the wpml-config.xml files to parse and setup filters
41 *
42 * @since 1.0
43 */
44 public function init() {
45 $this->xmls = array();
46
47 // Plugins
48 // 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
49 $plugins = ( is_multisite() && $sitewide_plugins = get_site_option( 'active_sitewide_plugins' ) ) && is_array( $sitewide_plugins ) ? array_keys( $sitewide_plugins ) : array();
50 $plugins = array_merge( $plugins, get_option( 'active_plugins', array() ) );
51
52 foreach ( $plugins as $plugin ) {
53 if ( file_exists( $file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
54 $this->xmls[ dirname( $plugin ) ] = $xml;
55 }
56 }
57
58 // Theme
59 if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
60 $this->xmls[ get_template() ] = $xml;
61 }
62
63 // Child theme
64 if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
65 $this->xmls[ get_stylesheet() ] = $xml;
66 }
67
68 // Custom
69 if ( file_exists( $file = PLL_LOCAL_DIR . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
70 $this->xmls['Polylang'] = $xml;
71 }
72
73 if ( ! empty( $this->xmls ) ) {
74 add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 20, 2 );
75 add_filter( 'pll_copy_term_metas', array( $this, 'copy_term_metas' ), 20, 2 );
76 add_filter( 'pll_get_post_types', array( $this, 'translate_types' ), 10, 2 );
77 add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
78
79 foreach ( $this->xmls as $context => $xml ) {
80 foreach ( $xml->xpath( 'admin-texts/key' ) as $key ) {
81 $attributes = $key->attributes();
82 $name = (string) $attributes['name'];
83 if ( PLL() instanceof PLL_Frontend ) {
84 $this->options[ $name ] = $key;
85 add_filter( 'option_' . $name, array( $this, 'translate_strings' ) );
86 } else {
87 $this->register_string_recursive( $context, get_option( $name ), $key );
88 }
89 }
90 }
91 }
92 }
93
94 /**
95 * Adds custom fields to the list of metas to copy when creating a new translation
96 *
97 * @since 1.0
98 *
99 * @param array $metas the list of custom fields to copy or synchronize
100 * @param bool $sync true for sync, false for copy
101 * @return array the list of custom fields to copy or synchronize
102 */
103 public function copy_post_metas( $metas, $sync ) {
104 foreach ( $this->xmls as $xml ) {
105 foreach ( $xml->xpath( 'custom-fields/custom-field' ) as $cf ) {
106 $attributes = $cf->attributes();
107 if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
108 $metas[] = (string) $cf;
109 } else {
110 $metas = array_diff( $metas, array( (string) $cf ) );
111 }
112 }
113 }
114 return $metas;
115 }
116
117 /**
118 * Adds term metas to the list of metas to copy when creating a new translation
119 *
120 * @since 2.6
121 *
122 * @param array $metas The list of term metas to copy or synchronize.
123 * @param bool $sync True for sync, false for copy.
124 * @return array The list of term metas to copy or synchronize.
125 */
126 public function copy_term_metas( $metas, $sync ) {
127 foreach ( $this->xmls as $xml ) {
128 foreach ( $xml->xpath( 'custom-term-fields/custom-term-field' ) as $cf ) {
129 $attributes = $cf->attributes();
130 if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
131 $metas[] = (string) $cf;
132 } else {
133 $metas = array_diff( $metas, array( (string) $cf ) );
134 }
135 }
136 }
137 return $metas;
138 }
139
140 /**
141 * Language and translation management for custom post types
142 *
143 * @since 1.0
144 *
145 * @param array $types list of post type names for which Polylang manages language and translations
146 * @param bool $hide true when displaying the list in Polylang settings
147 * @return array list of post type names for which Polylang manages language and translations
148 */
149 public function translate_types( $types, $hide ) {
150 foreach ( $this->xmls as $xml ) {
151 foreach ( $xml->xpath( 'custom-types/custom-type' ) as $pt ) {
152 $attributes = $pt->attributes();
153 if ( 1 == $attributes['translate'] && ! $hide ) {
154 $types[ (string) $pt ] = (string) $pt;
155 } else {
156 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
157 }
158 }
159 }
160 return $types;
161 }
162
163 /**
164 * Language and translation management for custom taxonomies
165 *
166 * @since 1.0
167 *
168 * @param array $taxonomies list of taxonomy names for which Polylang manages language and translations
169 * @param bool $hide true when displaying the list in Polylang settings
170 * @return array list of taxonomy names for which Polylang manages language and translations
171 */
172 public function translate_taxonomies( $taxonomies, $hide ) {
173 foreach ( $this->xmls as $xml ) {
174 foreach ( $xml->xpath( 'taxonomies/taxonomy' ) as $tax ) {
175 $attributes = $tax->attributes();
176 if ( 1 == $attributes['translate'] && ! $hide ) {
177 $taxonomies[ (string) $tax ] = (string) $tax;
178 } else {
179 unset( $taxonomies[ (string) $tax ] ); // the theme/plugin author decided what to do with the taxonomy so don't allow the user to change this
180 }
181 }
182 }
183 return $taxonomies;
184 }
185
186 /**
187 * Translates the strings for an option
188 *
189 * @since 1.0
190 *
191 * @param array|string $value Either a string to translate or a list of strings to translate
192 * @return array|string translated string(s)
193 */
194 public function translate_strings( $value ) {
195 $option = substr( current_filter(), 7 );
196 return $this->translate_strings_recursive( $value, $this->options[ $option ] );
197 }
198
199 /**
200 * Recursively registers strings for a serialized option
201 *
202 * @since 1.0
203 *
204 * @param string $context the group in which the strings will be registered
205 * @param array $options
206 * @param object $key XML node
207 */
208 protected function register_string_recursive( $context, $options, $key ) {
209 $children = $key->children();
210 if ( count( $children ) ) {
211 foreach ( $children as $child ) {
212 $attributes = $child->attributes();
213 $name = (string) $attributes['name'];
214 if ( '*' === $name && is_array( $options ) ) {
215 foreach ( $options as $n => $option ) {
216 $this->register_wildcard_options_recursive( $context, $option, $n );
217 }
218 } elseif ( isset( $options[ $name ] ) ) {
219 $this->register_string_recursive( $context, $options[ $name ], $child );
220 }
221 }
222 } else {
223 $attributes = $key->attributes();
224 pll_register_string( (string) $attributes['name'], $options, $context, true ); // Multiline as in WPML
225 }
226 }
227
228 /**
229 * Recursively registers strings with a wildcard
230 *
231 * @since 2.1
232 *
233 * @param string $context the group in which the strings will be registered
234 * @param array $options
235 * @param string $name Option name
236 */
237 protected function register_wildcard_options_recursive( $context, $options, $name ) {
238 if ( is_array( $options ) ) {
239 foreach ( $options as $n => $option ) {
240 $this->register_wildcard_options_recursive( $context, $option, $n );
241 }
242 } else {
243 pll_register_string( $name, $options, $context );
244 }
245 }
246
247 /**
248 * Recursively translates strings for a serialized option
249 *
250 * @since 1.0
251 *
252 * @param array|string $values either a string to translate or a list of strings to translate
253 * @param object $key XML node
254 * @return array|string translated string(s)
255 */
256 protected function translate_strings_recursive( $values, $key ) {
257 $children = $key->children();
258 if ( count( $children ) ) {
259 foreach ( $children as $child ) {
260 $attributes = $child->attributes();
261 $name = (string) $attributes['name'];
262 if ( '*' === $name && is_array( $values ) ) {
263 foreach ( $values as $n => $v ) {
264 $values[ $n ] = $this->translate_wildcard_options_recursive( $v, $n );
265 }
266 } elseif ( isset( $values[ $name ] ) ) {
267 $values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
268 }
269 }
270 } else {
271 $values = pll__( $values );
272 }
273 return $values;
274 }
275
276 /**
277 * Recursively translates strings registered by a wildcard
278 *
279 * @since 2.1
280 *
281 * @param array|string $options Either a string to translate or a list of strings to translate
282 * @param string $name Option name
283 * @return array|string Translated string(s)
284 */
285 protected function translate_wildcard_options_recursive( $options, $name ) {
286 if ( is_array( $options ) ) {
287 foreach ( $options as $n => $option ) {
288 $options[ $n ] = $this->translate_wildcard_options_recursive( $option, $n );
289 }
290 } else {
291 $options = pll__( $options );
292 }
293 return $options;
294 }
295 }
296