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

272 lines 8.6 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' ), 10, 2 );
75 add_filter( 'pll_get_post_types', array( $this, 'translate_types' ), 10, 2 );
76 add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
77
78 foreach ( $this->xmls as $context => $xml ) {
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 );
87 }
88 }
89 }
90 }
91 }
92
93 /**
94 * Adds custom fields to the list of metas to copy when creating a new translation
95 *
96 * @since 1.0
97 *
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
101 */
102 public function copy_post_metas( $metas, $sync ) {
103 foreach ( $this->xmls as $xml ) {
104 foreach ( $xml->xpath( 'custom-fields/custom-field' ) as $cf ) {
105 $attributes = $cf->attributes();
106 if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
107 $metas[] = (string) $cf;
108 } else {
109 $metas = array_diff( $metas, array( (string) $cf ) );
110 }
111 }
112 }
113 return $metas;
114 }
115
116 /**
117 * Language and translation management for custom post types
118 *
119 * @since 1.0
120 *
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
124 */
125 public function translate_types( $types, $hide ) {
126 foreach ( $this->xmls as $xml ) {
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
133 }
134 }
135 }
136 return $types;
137 }
138
139 /**
140 * Language and translation management for custom taxonomies
141 *
142 * @since 1.0
143 *
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
147 */
148 public function translate_taxonomies( $taxonomies, $hide ) {
149 foreach ( $this->xmls as $xml ) {
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
156 }
157 }
158 }
159 return $taxonomies;
160 }
161
162 /**
163 * Translates the strings for an option
164 *
165 * @since 1.0
166 *
167 * @param array|string $value Either a string to translate or a list of strings to translate
168 * @return array|string translated string(s)
169 */
170 public function translate_strings( $value ) {
171 $option = substr( current_filter(), 7 );
172 return $this->translate_strings_recursive( $value, $this->options[ $option ] );
173 }
174
175 /**
176 * Recursively registers strings for a serialized option
177 *
178 * @since 1.0
179 *
180 * @param string $context the group in which the strings will be registered
181 * @param array $options
182 * @param object $key XML node
183 */
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 ( '*' === $name && is_array( $options ) ) {
191 foreach ( $options as $n => $option ) {
192 $this->register_wildcard_options_recursive( $context, $option, $n );
193 }
194 } elseif ( isset( $options[ $name ] ) ) {
195 $this->register_string_recursive( $context, $options[ $name ], $child );
196 }
197 }
198 } else {
199 $attributes = $key->attributes();
200 pll_register_string( (string) $attributes['name'], $options, $context, true ); // Multiline as in WPML
201 }
202 }
203
204 /**
205 * Recursively registers strings with a wildcard
206 *
207 * @since 2.1
208 *
209 * @param string $context the group in which the strings will be registered
210 * @param array $options
211 * @param string $name Option name
212 */
213 protected function register_wildcard_options_recursive( $context, $options, $name ) {
214 if ( is_array( $options ) ) {
215 foreach ( $options as $n => $option ) {
216 $this->register_wildcard_options_recursive( $context, $option, $n );
217 }
218 } else {
219 pll_register_string( $name, $options, $context );
220 }
221 }
222
223 /**
224 * Recursively translates strings for a serialized option
225 *
226 * @since 1.0
227 *
228 * @param array|string $values either a string to translate or a list of strings to translate
229 * @param object $key XML node
230 * @return array|string translated string(s)
231 */
232 protected function translate_strings_recursive( $values, $key ) {
233 $children = $key->children();
234 if ( count( $children ) ) {
235 foreach ( $children as $child ) {
236 $attributes = $child->attributes();
237 $name = (string) $attributes['name'];
238 if ( '*' === $name && is_array( $values ) ) {
239 foreach ( $values as $n => $v ) {
240 $values[ $n ] = $this->translate_wildcard_options_recursive( $v, $n );
241 }
242 } elseif ( isset( $values[ $name ] ) ) {
243 $values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
244 }
245 }
246 } else {
247 $values = pll__( $values );
248 }
249 return $values;
250 }
251
252 /**
253 * Recursively translates strings registered by a wildcard
254 *
255 * @since 2.1
256 *
257 * @param array|string $options Either a string to translate or a list of strings to translate
258 * @param string $name Option name
259 * @return array|string Translated string(s)
260 */
261 protected function translate_wildcard_options_recursive( $options, $name ) {
262 if ( is_array( $options ) ) {
263 foreach ( $options as $n => $option ) {
264 $options[ $n ] = $this->translate_wildcard_options_recursive( $option, $n );
265 }
266 } else {
267 $options = pll__( $options );
268 }
269 return $options;
270 }
271 }
272