PluginProbe ʕ •ᴥ•ʔ
WPML Multilingual & Multicurrency for WooCommerce / 5.5.7
WPML Multilingual & Multicurrency for WooCommerce v5.5.7
5.5.7 5.3.8 5.3.9 5.4.3 5.4.4 5.4.5 5.5.1 5.5.1.1 5.5.2.2 5.5.2.3 5.5.3 5.5.3.1 5.5.4 5.5.5 5.5.6 trunk 0.9 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.2 2.3 2.3.1 2.3.2 3.0 3.0.1 3.1 3.2 3.2.1 3.2.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.4 3.4.1 3.4.2 3.4.3 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.6 3.6.1 3.6.10 3.6.11 3.6.2 3.6.3 3.6.4 3.6.5 3.6.5.1 3.6.6 3.6.7 3.6.8 3.6.9 3.7 3.7.1 3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.15 3.7.16 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.9.0 3.9.1 3.9.1.1 3.9.2 3.9.3 3.9.4 3.9.5 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.11.2 4.11.3.2 4.11.5 4.11.6 4.12.1 4.12.4 4.12.5 4.12.6 4.2.0 4.2.0.1 4.2.1 4.2.1.1 4.2.10 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.7.1 4.2.8 4.2.8.1 4.2.9 4.3.0 4.3.1 4.3.2 4.3.2.1 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.4.0 4.4.1 4.4.2 4.4.2.1 4.5.0 4.6.0 4.6.1 4.6.2 4.6.2.1 4.6.3 4.6.5 4.6.6 4.6.7 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 4.7.7 4.7.8 4.7.9 4.8.0 4.9.0 4.9.1 5.0.1 5.0.2 5.1.1 5.1.2 5.1.3 5.2.0 5.2.1 5.3.2 5.3.3.1 5.3.4 5.3.5 5.3.6 5.3.7
woocommerce-multilingual / inc / class-wcml-dependencies.php
woocommerce-multilingual / inc Last commit date
admin-menus 2 weeks ago currencies 2 weeks ago template-classes 2 weeks ago translation-editor 2 weeks ago class-wcml-ajax-setup.php 2 weeks ago class-wcml-attributes.php 2 weeks ago class-wcml-capabilities.php 2 weeks ago class-wcml-cart-removed-items-widget.php 1 year ago class-wcml-cart-switch-lang-functions.php 2 weeks ago class-wcml-cart-sync-warnings.php 2 weeks ago class-wcml-cart.php 2 weeks ago class-wcml-comments.php 2 weeks ago class-wcml-compatibility.php 2 weeks ago class-wcml-coupons.php 2 weeks ago class-wcml-dependencies.php 2 weeks ago class-wcml-emails.php 2 weeks ago class-wcml-endpoints.php 2 weeks ago class-wcml-install.php 2 weeks ago class-wcml-languages-upgrader.php 2 weeks ago class-wcml-locale.php 2 weeks ago class-wcml-orders.php 2 weeks ago class-wcml-products-screen-options.php 2 weeks ago class-wcml-products.php 2 weeks ago class-wcml-reports.php 2 weeks ago class-wcml-requests.php 2 weeks ago class-wcml-resources.php 2 weeks ago class-wcml-store-pages.php 2 weeks ago class-wcml-terms.php 2 weeks ago class-wcml-tp-support.php 2 weeks ago class-wcml-troubleshooting.php 2 weeks ago class-wcml-upgrade.php 2 weeks ago class-wcml-url-translation.php 2 weeks ago class-wcml-wc-gateways.php 2 weeks ago class-wcml-wc-shipping.php 2 weeks ago class-wcml-wc-strings.php 2 weeks ago class-wcml-widgets.php 2 weeks ago constants.php 2 weeks ago functions-pure.php 2 weeks ago functions.php 2 weeks ago installer-loader.php 2 weeks ago missing-php-functions.php 2 weeks ago wcml-core-functions.php 2 weeks ago wcml-switch-lang-request.php 2 weeks ago
class-wcml-dependencies.php
386 lines
1 <?php
2
3 class WCML_Dependencies {
4
5 const MIN_WPML = '4.3.5';
6 const MIN_WPML_ST = '3.0.5';
7 const MIN_WOOCOMMERCE = '3.9.0';
8
9 private $err_message = '';
10
11 private $allok;
12
13 private $tracking_link;
14
15 public $xml_config_errors = [];
16
17 public function __construct() {
18
19 if ( is_admin() ) {
20 add_action( 'init', [ $this, 'check_wpml_config' ], 100 );
21 }
22
23 $this->tracking_link = new WCML_Tracking_Link();
24 }
25
26 public function check() {
27 global $sitepress, $woocommerce;
28
29 if ( null === $this->allok ) {
30 $this->allok = true;
31
32 $missing = [];
33 $core_ok = true;
34 $st_ok = true;
35 $wc_ok = true;
36
37 if ( ! defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || is_null( $sitepress ) || ! class_exists( 'SitePress' ) ) {
38 $missing['WPML'] = $this->tracking_link->getWpmlHome();
39 $core_ok = false;
40 } elseif (
41 version_compare( ICL_SITEPRESS_VERSION, self::MIN_WPML, '<' )
42 ) {
43 add_action( 'admin_notices', [ $this, '_old_wpml_warning' ] );
44 $core_ok = false;
45 } elseif ( ! $sitepress->setup() ) {
46 if ( ! ( isset( $_GET['page'] ) && WPML_PLUGIN_FOLDER . '/menu/languages.php' === $_GET['page'] ) ) {
47 add_action( 'admin_notices', [ $this, '_wpml_not_installed_warning' ] );
48 }
49 $core_ok = false;
50 }
51
52 if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'WC' ) ) {
53 $missing['WooCommerce'] = 'http://www.woothemes.com/woocommerce/';
54 $wc_ok = false;
55 } elseif (
56 defined( 'WC_VERSION' ) && version_compare( WC_VERSION, self::MIN_WOOCOMMERCE, '<' ) ||
57 isset( $woocommerce->version ) && version_compare( $woocommerce->version, self::MIN_WOOCOMMERCE, '<' )
58 ) {
59 add_action( 'admin_notices', [ $this, '_old_wc_warning' ] );
60 $wc_ok = false;
61 }
62
63 if ( ! defined( 'WPML_ST_VERSION' ) ) {
64 $missing['WPML String Translation'] = $this->tracking_link->getWpmlStFaq();
65 $st_ok = false;
66 } elseif ( version_compare( WPML_ST_VERSION, self::MIN_WPML_ST, '<' ) ) {
67 add_action( 'admin_notices', [ $this, '_old_wpml_st_warning' ] );
68 $st_ok = false;
69 }
70
71 $has_no_wpml_plugin = ! ( $core_ok || $st_ok );
72 $full_mode = $core_ok && $st_ok && $wc_ok;
73 $standalone = $has_no_wpml_plugin && $wc_ok;
74 $this->allok = $full_mode || $standalone;
75
76 if ( ! $this->allok && count( $missing ) ) {
77 $possibly_standalone = $has_no_wpml_plugin && ! $wc_ok;
78 add_action( 'admin_notices', self::show_missing_plugins_warning( $missing, $possibly_standalone ) );
79 }
80
81 if ( $full_mode ) {
82 $this->check_for_incompatible_permalinks();
83 add_action( 'init', [ $this, 'check_for_translatable_default_taxonomies' ] );
84 }
85
86 if ( $sitepress instanceof SitePress ) {
87 $this->allok = $full_mode && $sitepress->setup();
88 }
89 }
90
91 return $this->allok;
92 }
93
94 public function _old_wpml_warning() {
95 ?>
96 <div class="message error">
97 <p>
98 <?php
99 printf(
100 /* translators: %1$s is a URL and %2$s is a version number */
101 __(
102 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">WPML</a> versions prior %2$s.',
103 'woocommerce-multilingual'
104 ),
105 $this->tracking_link->getWpmlHome(),
106 self::MIN_WPML
107 );
108 ?>
109 </p>
110 </div>
111 <?php
112 }
113
114 public function _wpml_not_installed_warning() {
115 ?>
116 <div class="message error">
117 <p><?php printf( __( 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. Please finish the installation of WPML first.', 'woocommerce-multilingual' ) ); ?></p>
118 </div>
119 <?php
120 }
121
122 public function _old_wc_warning() {
123 ?>
124 <div class="message error">
125 <p>
126 <?php
127 printf(
128 /* translators: %1$s is a URL and %2$s is a version number */
129 __(
130 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">Woocommerce</a> versions prior %2$s.',
131 'woocommerce-multilingual'
132 ),
133 'http://www.woothemes.com/woocommerce/',
134 self::MIN_WOOCOMMERCE
135 );
136 ?>
137 </p>
138 </div>
139 <?php
140 }
141
142 public function _old_wpml_st_warning() {
143 ?>
144 <div class="message error">
145 <p>
146 <?php
147 printf(
148 /* translators: %1$s is a URL and %2$s is a version number */
149 __(
150 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">WPML String Translation</a> versions prior %2$s.',
151 'woocommerce-multilingual'
152 ),
153 $this->tracking_link->getWpmlHome(),
154 self::MIN_WPML_ST
155 );
156 ?>
157 </p>
158 </div>
159 <?php
160 }
161
162 public function check_for_translatable_default_taxonomies() {
163
164 $default_taxonomies = [
165 \WCML\Utilities\WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY,
166 \WCML\Utilities\WCTaxonomies::TAXONOMY_PRODUCT_TAG,
167 ];
168 $show_error = false;
169
170 foreach ( $default_taxonomies as $taxonomy ) {
171 if ( ! is_taxonomy_translated( $taxonomy ) ) {
172 $show_error = true;
173 break;
174 }
175 }
176
177 if ( $show_error ) {
178 $support_link = '<a href="' . WCML_Tracking_Link::getWpmlSupport() . '">' . __( 'WPML support', 'woocommerce-multilingual' ) . '</a>';
179
180 /* translators: Part 1/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
181 $sentences[] = _x( "Some taxonomies in your site are forced to be untranslatable. This is causing a problem when you're trying to run a multilingual WooCommerce site.", 'Default taxonomies must be translatable: 1/6', 'woocommerce-multilingual' );
182 /* translators: Part 2/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
183 $sentences[] = _x( 'A plugin or the theme are probably doing this.', 'Default taxonomies must be translatable: 2/6', 'woocommerce-multilingual' );
184 /* translators: Part 3/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
185 $sentences[] = _x( 'What you can do:', 'Default taxonomies must be translatable: 3/6', 'woocommerce-multilingual' );
186 /* translators: Part 4/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
187 $sentences[] = _x( '1. Temporarily disable plugins and see if this message disappears.', 'Default taxonomies must be translatable: 4/6', 'woocommerce-multilingual' );
188 /* translators: Part 5/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
189 $sentences[] = _x( '2. Temporarily switch the theme and see if this message disappears.', 'Default taxonomies must be translatable: 5/6', 'woocommerce-multilingual' );
190 /* translators: Part 6/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */
191 $sentences[] = sprintf( _x( "It's best to contact %s, tell that you're getting this message and offer to send a Duplicator copy of the site. We will work with the theme/plugin author and fix the problem for good. In the meanwhile, we'll give you a temporary solution, so you're not stuck.", 'Default taxonomies must be translatable: 6/6', 'woocommerce-multilingual' ), $support_link );
192
193 $this->err_message = '<div class="message error"><p>' . implode( '</p><p>', $sentences ) . '</p></div>';
194 add_action( 'admin_notices', [ $this, 'plugin_notice_message' ] );
195 }
196 }
197
198 private static function show_missing_plugins_warning( $missing_plugins, $possibly_standalone ) {
199 return function() use ( $missing_plugins, $possibly_standalone ) {
200 if ( $possibly_standalone ) {
201 $missing_plugins = array_intersect_key( $missing_plugins, [ 'WooCommerce' => 1 ] );
202 }
203
204 $missing = '';
205 $counter = 0;
206 foreach ( $missing_plugins as $title => $url ) {
207 $counter ++;
208 if ( $counter == sizeof( $missing_plugins ) ) {
209 $sep = '';
210 } elseif ( $counter == sizeof( $missing_plugins ) - 1 ) {
211 $sep = ' ' . __( 'and', 'woocommerce-multilingual' ) . ' ';
212 } else {
213 $sep = ', ';
214 }
215 $missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep;
216 }
217 ?>
218
219 <div class="message error">
220 <p><?php
221 /* translators: %s is a list of plugin names */
222 printf( __( 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It requires %s in order to work.', 'woocommerce-multilingual' ), $missing );
223 ?></p>
224 </div>
225 <?php
226 };
227 }
228
229 private function check_for_incompatible_permalinks() {
230 global $sitepress_settings, $pagenow;
231
232 $permalinks = get_option( 'woocommerce_permalinks', [ 'product_base' => '' ] );
233 if ( empty( $permalinks['product_base'] ) ) {
234 return;
235 }
236
237 $tm_folder = defined( 'WPML_TM_FOLDER' ) ? WPML_TM_FOLDER : 'tm';
238
239 $message = __( 'Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual' );
240 $message .= '<br /><br />';
241 $message .= __( 'Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual' );
242 $message .= '<br /><br />';
243 $message .= '<a href="' . admin_url( 'options-permalink.php' ) . '">' . __( 'Permalink settings', 'woocommerce-multilingual' ) . '</a>';
244 $message .= ' | ';
245 $message .= '<a href="' . admin_url( 'admin.php?page=' . $tm_folder . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options' ) . '">' . __( 'Configure products slug translation', 'woocommerce-multilingual' ) . '</a>';
246
247 $compatible = true;
248 $permalink_structure = get_option( 'permalink_structure' );
249 if ( empty( $permalink_structure )
250 && ! empty( $sitepress_settings['posts_slug_translation']['on'] )
251 && ! empty( $sitepress_settings['posts_slug_translation']['types'] )
252 && $sitepress_settings['posts_slug_translation']['types']['product'] ) {
253 $compatible = false;
254 }
255
256 if ( ! $compatible && ( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && \WCML\Utilities\AdminUrl::PAGE_WPML_WCML == $_GET['page'] ) ) ) {
257 $this->err_message = '<div class="message error"><p>' . $message . ' </p></div>';
258 add_action( 'admin_notices', [ $this, 'plugin_notice_message' ] );
259 }
260 }
261
262 public function plugin_notice_message() {
263 echo $this->err_message;
264 }
265
266 public function check_wpml_config() {
267 global $sitepress_settings, $sitepress, $woocommerce_wpml;
268
269 if ( empty( $sitepress_settings ) || ! $this->check() ) {
270 return;
271 }
272
273 $file = realpath( WCML_PLUGIN_PATH . '/wpml-config.xml' );
274 if ( ! file_exists( $file ) ) {
275 $this->xml_config_errors[] = __( 'wpml-config.xml file missing from WPML Multilingual & Multicurrency for WooCommerce folder.', 'woocommerce-multilingual' );
276 } else {
277 $config = icl_xml2array( file_get_contents( $file ) );
278
279 if ( isset( $config['wpml-config'] ) ) {
280 $cfs = [];
281
282 if ( isset( $config['wpml-config']['custom-fields'] ) ) {
283 if ( isset( $config['wpml-config']['custom-fields']['custom-field']['value'] ) ) {
284 $cfs[] = $config['wpml-config']['custom-fields']['custom-field'];
285 } else {
286 foreach ( $config['wpml-config']['custom-fields']['custom-field'] as $cf ) {
287 $cfs[] = $cf;
288 }
289 }
290
291 if ( $cfs ) {
292 foreach ( $cfs as $cf ) {
293 if ( ! isset( $sitepress_settings['translation-management']['custom_fields_translation'][ $cf['value'] ] ) ) {
294 continue;
295 }
296
297 $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][ $cf['value'] ];
298 $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ( $cf['attr']['action'] == 'translate' ? 2 : 0 );
299
300 if ( $effective_config_value != $correct_config_value ) {
301 /* translators: %s is a field name */
302 $this->xml_config_errors[] = sprintf( __( 'Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $cf['value'] . '</i>' );
303 }
304 }
305 }
306 }
307
308 if ( isset( $config['wpml-config']['custom-types'] ) ) {
309 $cts = [];
310
311 if ( isset( $config['wpml-config']['custom-types']['custom-type']['value'] ) ) {
312 $cts[] = $config['wpml-config']['custom-types']['custom-type'];
313 } else {
314 foreach ( $config['wpml-config']['custom-types']['custom-type'] as $cf ) {
315 $cts[] = $cf;
316 }
317 }
318
319 if ( $cts ) {
320 foreach ( $cts as $ct ) {
321 if ( ! isset( $sitepress_settings['custom_posts_sync_option'][ $ct['value'] ] ) ) {
322 continue;
323 }
324 $effective_config_value = $sitepress_settings['custom_posts_sync_option'][ $ct['value'] ];
325 $correct_config_value = $ct['attr']['translate'];
326
327 if ( 'product' === $ct['value'] && $woocommerce_wpml->products->is_product_display_as_translated_post_type() ) {
328 $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED;
329 }
330
331 if ( $effective_config_value != $correct_config_value ) {
332 /* translators: %s is a custom post type name */
333 $this->xml_config_errors[] = sprintf( __( 'Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $ct['value'] . '</i>' );
334 }
335 }
336 }
337 }
338
339 if ( isset( $config['wpml-config']['taxonomies'] ) ) {
340 $txs = [];
341
342 if ( isset( $config['wpml-config']['taxonomies']['taxonomy']['value'] ) ) {
343 $txs[] = $config['wpml-config']['taxonomies']['taxonomy'];
344 } else {
345 foreach ( $config['wpml-config']['taxonomies']['taxonomy'] as $cf ) {
346 $txs[] = $cf;
347 }
348 }
349
350 if ( $txs ) {
351 foreach ( $txs as $tx ) {
352 if ( ! isset( $sitepress_settings['taxonomies_sync_option'][ $tx['value'] ] ) ) {
353 continue;
354 }
355 $effective_config_value = $sitepress_settings['taxonomies_sync_option'][ $tx['value'] ];
356 $correct_config_value = $tx['attr']['translate'];
357
358 if ( method_exists( $sitepress, 'is_display_as_translated_taxonomy' ) && $sitepress->is_display_as_translated_taxonomy( $tx['value'] ) ) {
359 $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED;
360 }
361
362 if ( $effective_config_value != $correct_config_value ) {
363 /* translators: %s is a custom taxonomy name */
364 $this->xml_config_errors[] = sprintf( __( 'Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $tx['value'] . '</i>' );
365 }
366 }
367 }
368 }
369 }
370 }
371
372 }
373
374 public function required_plugin_install_link( $repository = 'wpml' ) {
375
376 if ( class_exists( 'WP_Installer_API' ) ) {
377 $url = WP_Installer_API::get_product_installer_link( $repository );
378 } else {
379 $url = $this->tracking_link->getWpmlHome();
380 }
381
382 return $url;
383 }
384
385 }
386