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-install.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-install.php
369 lines
1 <?php
2
3 use WCML\COT\Helper as COTHelper;
4 use function WCML\functions\isStandAlone;
5
6 class WCML_Install {
7
8 const CHUNK_SIZE = 1000;
9
10 public static function initialize( $woocommerce_wpml, $sitepress ) {
11 if ( is_admin() ) {
12
13 if ( isStandAlone() ) {
14 self::initialize_standalone( $woocommerce_wpml );
15 } else {
16 self::initialize_full( $woocommerce_wpml, $sitepress );
17 }
18 }
19 }
20
21 private static function initialize_full( $woocommerce_wpml, SitePress $sitepress ) {
22 if ( empty( $woocommerce_wpml->settings['set_up'] ) ) {
23
24 if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
25 add_action( 'init', [ $woocommerce_wpml->terms, 'sync_term_order_globally' ], 20 );
26 }
27
28 if ( ! isset( $woocommerce_wpml->settings['wc_admin_options_saved'] ) ) {
29 self::handle_admin_texts();
30 $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
31 }
32
33 if ( $woocommerce_wpml->is_wpml_prior_4_2() ) {
34 if ( ! isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
35 $woocommerce_wpml->settings['trnsl_interface'] = 1;
36 }
37 } else {
38 global $iclTranslationManagement;
39 $iclTranslationManagement->settings[ WPML_TM_Post_Edit_TM_Editor_Mode::TM_KEY_FOR_POST_TYPE_USE_NATIVE ]['product'] = false;
40 $iclTranslationManagement->save_settings();
41 }
42
43 if ( ! isset( $woocommerce_wpml->settings['products_sync_date'] ) ) {
44 $woocommerce_wpml->settings['products_sync_date'] = 1;
45 }
46
47 if ( ! isset( $woocommerce_wpml->settings['products_sync_order'] ) ) {
48 $woocommerce_wpml->settings['products_sync_order'] = 1;
49 }
50
51 if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
52 $woocommerce_wpml->settings['display_custom_prices'] = 0;
53 }
54
55 if ( ! isset( $woocommerce_wpml->settings['sync_taxonomies_checked'] ) ) {
56 $woocommerce_wpml->terms->check_if_sync_terms_needed();
57 $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
58 }
59
60 WCML_Capabilities::set_up_capabilities();
61
62 self::set_language_information( $sitepress );
63 self::check_product_type_terms();
64
65 set_transient( '_wcml_activation_redirect', 1, 30 );
66
67 WPML_Config::load_config_run();
68
69 add_action( 'init', [ __CLASS__, 'insert_default_categories' ] );
70
71 self::set_language_to_existing_orders( $sitepress->get_default_language() );
72
73 wp_schedule_single_event( time() + 10, 'generate_category_lookup_table' );
74
75 $woocommerce_wpml->settings['set_up'] = 1;
76 $woocommerce_wpml->update_settings();
77 }
78
79 if ( empty( $woocommerce_wpml->settings['downloaded_translations_for_wc'] ) ) {
80 $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
81 $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
82 $woocommerce_wpml->update_settings();
83 }
84
85 if ( empty( $woocommerce_wpml->settings['rewrite_rules_flashed'] ) ) {
86 flush_rewrite_rules();
87 $woocommerce_wpml->settings['rewrite_rules_flashed'] = 1;
88 }
89
90 add_filter(
91 'wpml_tm_dashboard_translatable_types',
92 [
93 __CLASS__,
94 'hide_variation_type_on_tm_dashboard',
95 ]
96 );
97
98 $WCML_Setup_UI = new WCML_Setup_UI();
99 $WCML_Setup_UI->add_hooks();
100 $WCML_Setup = new WCML_Setup( $WCML_Setup_UI, new WCML_Setup_Handlers( $woocommerce_wpml ), $woocommerce_wpml, $sitepress );
101 $WCML_Setup->setup_redirect();
102 $WCML_Setup->add_hooks();
103
104 $translated_product_type_terms = self::translated_product_type_terms();
105 if ( ! empty( $translated_product_type_terms ) ) {
106 add_action( 'admin_notices', [ __CLASS__, 'admin_translated_product_type_terms_notice' ] );
107 } elseif ( $sitepress->is_translated_taxonomy( 'product_type' ) ) {
108 add_action( 'admin_notices', [ __CLASS__, 'admin_translated_product_type_notice' ] );
109 }
110 }
111
112 private static function initialize_standalone( $woocommerce_wpml ) {
113 if ( empty( $woocommerce_wpml->settings['set_up_standalone'] ) ) {
114 if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
115 $woocommerce_wpml->settings['display_custom_prices'] = 0;
116 }
117
118 WCML_Capabilities::set_up_capabilities();
119
120 set_transient( '_wcml_activation_redirect', 1, 30 );
121
122 $woocommerce_wpml->settings['set_up_standalone'] = 1;
123 $woocommerce_wpml->update_settings();
124 }
125 }
126
127 private static function set_language_information( $sitepress ) {
128 global $wpdb;
129
130 $def_lang = $sitepress->get_default_language();
131 $products = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'" );
132 foreach ( $products as $product ) {
133 $exist = $sitepress->get_language_for_element( $product->ID, 'post_product' );
134 if ( ! $exist ) {
135 $sitepress->set_element_language_details( $product->ID, 'post_product', false, $def_lang );
136 }
137 }
138
139 $terms = $wpdb->get_results( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'" );
140 foreach ( $terms as $term ) {
141 $exist = $sitepress->get_language_for_element( $term->term_taxonomy_id, 'tax_product_cat' );
142 if ( ! $exist ) {
143 $sitepress->set_element_language_details( $term->term_taxonomy_id, 'tax_product_cat', false, $def_lang );
144 }
145 }
146 $terms = $wpdb->get_results( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'" );
147 foreach ( $terms as $term ) {
148 $exist = $sitepress->get_language_for_element( $term->term_taxonomy_id, 'tax_product_tag' );
149 if ( ! $exist ) {
150 $sitepress->set_element_language_details( $term->term_taxonomy_id, 'tax_product_tag', false, $def_lang );
151 }
152 }
153
154 $terms = $wpdb->get_results( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'" );
155 foreach ( $terms as $term ) {
156 $exist = $sitepress->get_language_for_element( $term->term_taxonomy_id, 'tax_product_shipping_class' );
157 if ( ! $exist ) {
158 $sitepress->set_element_language_details( $term->term_taxonomy_id, 'tax_product_shipping_class', false, $def_lang );
159 }
160 }
161 }
162
163 public static function check_product_type_terms() {
164 global $wpdb;
165 $translations = self::translated_product_type_terms();
166
167 if ( $translations ) {
168 foreach ( $translations as $translation ) {
169 if ( ! is_null( $translation->source_language_code ) ) {
170 $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
171 if ( $term_relationships ) {
172 $orig_term = $wpdb->get_var( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type' AND trid = %d AND source_language_code IS NULL", $translation->trid ) );
173 if ( $orig_term ) {
174 foreach ( $term_relationships as $term_relationship ) {
175 $wpdb->update(
176 $wpdb->term_relationships,
177 [
178 'term_taxonomy_id' => $orig_term,
179 ],
180 [
181 'object_id' => $term_relationship->object_id,
182 'term_taxonomy_id' => $translation->element_id,
183 ]
184 );
185 }
186 }
187 }
188 $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
189
190 if ( $term_id ) {
191 $wpdb->delete(
192 $wpdb->terms,
193 [
194 'term_id' => $term_id,
195 ]
196 );
197
198 $wpdb->delete(
199 $wpdb->term_taxonomy,
200 [
201 'term_taxonomy_id' => $translation->element_id,
202 ]
203 );
204 }
205 }
206 }
207
208 foreach ( $translations as $translation ) {
209 $wpdb->delete(
210 $wpdb->prefix . 'icl_translations',
211 [
212 'translation_id' => $translation->translation_id,
213 ]
214 );
215 }
216 }
217 }
218
219 public static function translated_product_type_terms() {
220 global $wpdb;
221 $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
222
223 return $translations;
224 }
225
226 private static function handle_admin_texts() {
227 if ( class_exists( 'WooCommerce' ) ) {
228 $emails = new WC_Emails();
229 foreach ( $emails->emails as $email ) {
230 $option_name = $email->plugin_id . $email->id . '_settings';
231 if ( ! get_option( $option_name ) ) {
232 add_option( $option_name, $email->settings );
233 }
234 }
235 }
236 }
237
238 public static function admin_translated_product_type_notice() {
239 ?>
240
241 <div id="message" class="updated error">
242 <p>
243 <?php
244 /* translators: %1$s and %2$s are opening and closing HTML italic tags and %3$s and %4$s are opening and closing HTML link tags */
245 printf( esc_html__( 'We detected a problem in your WPML configuration: the %1$sproduct_type%2$s taxonomy is set as translatable and this would cause problems with translated products. You can fix this in the %3$sMultilingual Content Setup page%4$s.', 'woocommerce-multilingual' ), '<i>', '</i>', '<a href="' . esc_url( admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#ml-content-setup-sec-8' ) ) . '">', '</a>' );
246 ?>
247 </p>
248 </div>
249
250 <?php
251 }
252
253 public static function admin_translated_product_type_terms_notice() {
254 ?>
255
256 <div id="message" class="updated error">
257 <p>
258 <?php
259 printf(
260 /* translators: %1$s and %2$s are opening and closing HTML italic tags and %3$s and %4$s are opening and closing HTML link tags */
261 esc_html__( 'We detected that the %1$sproduct_type%2$s field was set incorrectly for some product translations. This happened because the product_type taxonomy was translated. You can fix this in the WPML Multilingual & Multicurrency for WooCommerce %3$stroubleshooting page%4$s.', 'woocommerce-multilingual' ),
262 '<i>',
263 '</i>',
264 '<a href="' . esc_url( \WCML\Utilities\AdminUrl::getTroubleshootingTab() ) . '">',
265 '</a>'
266 );
267 ?>
268 </p>
269 </div>
270
271 <?php
272 }
273
274 public static function hide_variation_type_on_tm_dashboard( $types ) {
275 unset( $types['product_variation'] );
276 return $types;
277 }
278
279 public static function insert_default_categories() {
280 global $sitepress, $woocommerce_wpml;
281
282 $settings = $woocommerce_wpml->get_settings();
283
284 $default_language = $sitepress->get_default_language();
285 $default_categories = $settings['default_categories'] ?? [];
286
287 foreach ( $sitepress->get_active_languages() as $language ) {
288 if ( isset( $default_categories[ $language['code'] ] ) ) {
289 continue;
290 }
291
292 $sitepress->switch_locale( $language['code'] );
293 $translated_cat_name = __( 'Uncategorized', 'sitepress' );
294 $translated_cat_name = 'Uncategorized' === $translated_cat_name && 'en' !== $language['code'] ? 'Uncategorized @' . $language['code'] : $translated_cat_name;
295 $translated_term = get_term_by( 'name', $translated_cat_name, 'product_cat', ARRAY_A );
296 $sitepress->switch_locale();
297
298 if ( ! $translated_term ) {
299 $translated_term = wp_insert_term( $translated_cat_name, 'product_cat' );
300 }
301
302 if ( ! is_wp_error( $translated_term ) && is_array( $translated_term ) ) {
303 $settings['default_categories'][ $language['code'] ] = $translated_term['term_taxonomy_id'];
304
305 $default_category_trid = $sitepress->get_element_trid(
306 get_option( 'default_product_cat' ),
307 'tax_product_cat'
308 );
309 $sitepress->set_element_language_details(
310 $translated_term['term_taxonomy_id'],
311 'tax_product_cat',
312 $default_category_trid,
313 $language['code'],
314 $default_language
315 );
316 }
317 }
318
319 $woocommerce_wpml->update_settings( $settings );
320 }
321
322 public static function set_language_to_existing_orders( $default_language ) {
323 global $wpdb;
324
325 $orders_needs_set_language = $wpdb->get_col(
326 "SELECT DISTINCT( pm.post_id ) FROM {$wpdb->postmeta} AS pm
327 INNER JOIN {$wpdb->posts} AS p ON pm.post_id = p.ID
328 WHERE p.post_type = 'shop_order' AND pm.post_id NOT IN
329 ( SELECT DISTINCT( post_id ) FROM {$wpdb->postmeta} WHERE meta_key = '" . WCML_Orders::KEY_LANGUAGE . "' )"
330 );
331
332 $values_query = function ( $order_id ) use ( $wpdb, $default_language ) {
333 return $wpdb->prepare(
334 '(%d, %s, %s)',
335 $order_id,
336 WCML_Orders::KEY_LANGUAGE,
337 $default_language
338 );
339 };
340
341 wpml_collect( array_chunk( $orders_needs_set_language, self::CHUNK_SIZE ) )->each( function ( $chunk ) use ( $values_query, $wpdb ) {
342
343 $query = "INSERT IGNORE INTO {$wpdb->postmeta} (`post_id`, `meta_key`, `meta_value`) VALUES ";
344 $query .= implode( ',', array_map( $values_query, $chunk ) );
345
346 $wpdb->query( $query );
347 } );
348
349 if ( COTHelper::getTableExists() ) {
350 $orderTable = COTHelper::getTableName();
351 $orderMetaTable = COTHelper::getMetaTableName();
352
353 $wpdb->query(
354 $wpdb->prepare(
355 "
356 INSERT IGNORE INTO {$orderMetaTable} (order_id, meta_key, meta_value)
357 SELECT o.id, '" . WCML_Orders::KEY_LANGUAGE . "' AS meta_key, %s AS meta_value
358 FROM {$orderTable} o
359 LEFT JOIN {$orderMetaTable} om ON o.id = om.order_id AND om.meta_key = '" . WCML_Orders::KEY_LANGUAGE . "'
360 WHERE om.id IS NULL
361 ",
362 $default_language
363 )
364 );
365 }
366 }
367
368 }
369