PluginProbe
Polylang / 2.7.0.1
Polylang v2.7.0.1
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.7.0.1, at modules/wpml/wpml-config.php

284 lines 9.5 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, $name, 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 * @since 2.7 Signature modified
204 *
205 * @param string $context The group in which the strings will be registered.
206 * @param string $option Option name.
207 * @param array $values Option value.
208 * @param object $key XML node.
209 */
210 protected function register_string_recursive( $context, $option, $values, $key ) {
211 $children = $key->children();
212 if ( count( $children ) ) {
213 foreach ( $children as $child ) {
214 $attributes = $child->attributes();
215 $name = (string) $attributes['name'];
216 if ( '*' === $name && is_array( $values ) ) {
217 // This case could be handled by the next one, but we avoid calls to preg_match here.
218 foreach ( $values as $n => $value ) {
219 $this->register_string_recursive( $context, $n, $value, $child );
220 }
221 } elseif ( false !== strpos( $name, '*' ) ) {
222 $pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
223 foreach ( $values as $n => $value ) {
224 if ( preg_match( $pattern, $n ) ) {
225 $this->register_string_recursive( $context, $n, $value, $child );
226 }
227 }
228 } elseif ( isset( $values[ $name ] ) ) {
229 $this->register_string_recursive( $context, $name, $values[ $name ], $child );
230 }
231 }
232 } elseif ( is_array( $values ) ) {
233 // Parent key is a wildcard and no sub-key has been whitelisted.
234 foreach ( $values as $n => $value ) {
235 $this->register_string_recursive( $context, $n, $value, $key );
236 }
237 } else {
238 pll_register_string( $option, $values, $context, true ); // Multiline as in WPML.
239 }
240 }
241
242 /**
243 * Recursively translates strings for a serialized option
244 *
245 * @since 1.0
246 *
247 * @param array|string $values Either a string to translate or a list of strings to translate.
248 * @param object $key XML node.
249 * @return array|string Translated string(s)
250 */
251 protected function translate_strings_recursive( $values, $key ) {
252 $children = $key->children();
253 if ( count( $children ) ) {
254 foreach ( $children as $child ) {
255 $attributes = $child->attributes();
256 $name = (string) $attributes['name'];
257 if ( '*' === $name && is_array( $values ) ) {
258 // This case could be handled by the next one, but we avoid calls to preg_match here.
259 foreach ( $values as $n => $value ) {
260 $values[ $n ] = $this->translate_strings_recursive( $value, $child );
261 }
262 } elseif ( false !== strpos( $name, '*' ) ) {
263 $pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
264 foreach ( $values as $n => $value ) {
265 if ( preg_match( $pattern, $n ) ) {
266 $values[ $n ] = $this->translate_strings_recursive( $value, $child );
267 }
268 }
269 } elseif ( isset( $values[ $name ] ) ) {
270 $values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
271 }
272 }
273 } elseif ( is_array( $values ) ) {
274 // Parent key is a wildcard and no sub-key has been whitelisted.
275 foreach ( $values as $n => $value ) {
276 $values[ $n ] = $this->translate_strings_recursive( $value, $key );
277 }
278 } else {
279 $values = pll__( $values );
280 }
281 return $values;
282 }
283 }
284