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-terms.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-terms.php
1079 lines
1 <?php
2
3 use function WCML\functions\getSetting;
4 use WCML\Utilities\WCTaxonomies;
5
6 class WCML_Terms {
7 const PRIORITY_AFTER_WC_CACHE_HELPER = 20;
8
9 const PRODUCT_SHIPPING_CLASS = 'product_shipping_class';
10 private $ALL_TAXONOMY_TERMS_TRANSLATED = 0;
11 private $NEW_TAXONOMY_TERMS = 1;
12 private $NEW_TAXONOMY_IGNORED = 2;
13
14 private $woocommerce_wpml;
15 private $sitepress;
16 private $wpdb;
17
18 public function __construct( woocommerce_wpml $woocommerce_wpml, \WPML\Core\ISitePress $sitepress, wpdb $wpdb ) {
19 $this->woocommerce_wpml = $woocommerce_wpml;
20 $this->sitepress = $sitepress;
21 $this->wpdb = $wpdb;
22 }
23
24 public function add_hooks() {
25 if ( 1 === getSetting( 'products_sync_order', 1 ) ) {
26 add_action( 'update_term_meta', [ $this, 'sync_term_order' ], 100, 4 );
27 }
28
29 add_action( 'created_term', [ $this, 'translated_terms_status_update' ], 10, 3 );
30 add_action( 'edit_term', [ $this, 'translated_terms_status_update' ], 10, 3 );
31
32 add_action( 'created_term', [ $this, 'set_flag_for_variation_on_attribute_update' ], 10, 3 );
33
34 add_filter( 'wpml_taxonomy_translation_bottom', [ $this, 'sync_taxonomy_translations' ], 10, 3 );
35
36 add_action( 'wp_ajax_wcml_sync_product_variations', [ $this, 'wcml_sync_product_variations' ] );
37 add_action( 'wp_ajax_wcml_tt_sync_taxonomies_in_content', [ $this, 'wcml_sync_taxonomies_in_content' ] );
38 add_action(
39 'wp_ajax_wcml_tt_sync_taxonomies_in_content_preview',
40 [
41 $this,
42 'wcml_sync_taxonomies_in_content_preview',
43 ]
44 );
45
46 if ( is_admin() ) {
47 add_action( 'admin_menu', [ $this, 'admin_menu_setup' ] );
48
49 add_filter( 'pre_option_default_product_cat', [ $this, 'pre_option_default_product_cat' ] );
50 add_filter( 'update_option_default_product_cat', [ $this, 'update_option_default_product_cat' ], 1, 2 );
51 }
52
53 add_action( 'delete_term', [ $this, 'wcml_delete_term' ], 10, 4 );
54 add_filter( 'get_the_terms', [ $this, 'shipping_terms' ], 10, 3 );
55 add_filter( 'get_terms', [ $this, 'filter_shipping_classes_terms' ], 10, 3 );
56
57 add_filter( 'woocommerce_get_product_terms', [ $this, 'get_product_terms_filter' ], 10, 4 );
58 add_action( 'created_term_translation', [ $this, 'set_flag_to_sync' ], 10, 3 );
59
60 add_filter( 'woocommerce_get_product_subcategories_cache_key', [ $this, 'add_lang_parameter_to_cache_key' ] );
61
62 add_action( 'clean_term_cache', [ $this, 'flush_term_cache_added_by_wc_and_wcml' ], self::PRIORITY_AFTER_WC_CACHE_HELPER, 2 );
63 add_action( 'edit_terms', [ $this, 'flush_term_cache_added_by_wc_and_wcml' ], self::PRIORITY_AFTER_WC_CACHE_HELPER, 2 );
64 }
65
66 public function admin_menu_setup() {
67 global $pagenow;
68 if ( $pagenow == 'edit-tags.php' && isset( $_GET['action'] ) && $_GET['action'] == 'edit' ) {
69 add_action( 'admin_notices', [ $this, 'show_term_translation_screen_notices' ] );
70 }
71
72 $page = $_GET['page'] ?? '';
73 if ( $page === WPML_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' ) {
74 WCML_Resources::load_management_css();
75 WCML_Resources::load_taxonomy_translation_scripts();
76 }
77
78 }
79
80 public function show_term_translation_screen_notices() {
81
82 $taxonomies = array_keys( get_taxonomies( [ 'object_type' => [ 'product' ] ], 'objects' ) );
83 $taxonomies = $taxonomies + array_keys( get_taxonomies( [ 'object_type' => [ 'product_variations' ] ], 'objects' ) );
84 $taxonomies = array_unique( $taxonomies );
85 $taxonomy = $_GET['taxonomy'] ?? false;
86 if ( $taxonomy && in_array( $taxonomy, $taxonomies ) ) {
87 $taxonomy_obj = get_taxonomy( $taxonomy );
88 $message = sprintf(
89 /* translators: %1$s/%2$s and %3$s/%4$s are opening and closing HTML link tags */
90 __( 'To translate %1$s please use the %2$s translation%3$s page, inside the %4$sWPML Multilingual & Multicurrency for WooCommerce admin%5$s.', 'woocommerce-multilingual' ),
91 $taxonomy_obj->labels->name,
92 '<strong><a href="' . \WCML\Utilities\AdminUrl::getTab( $taxonomy ) . '">' . $taxonomy_obj->labels->singular_name,
93 '</a></strong>',
94 '<strong><a href="' . \WCML\Utilities\AdminUrl::getMultilingualTab() .'">',
95 '</a></strong>'
96 );
97
98 echo '<div class="updated"><p>' . $message . '</p></div>';
99 }
100
101 }
102
103 public function sync_term_order_globally() {
104 if ( ! defined( 'WOOCOMMERCE_VERSION' ) ) {
105 return;
106 }
107
108 $cur_lang = $this->sitepress->get_current_language();
109 $lang = $this->sitepress->get_default_language();
110 $this->sitepress->switch_lang( $lang );
111
112 $taxes = wc_get_attribute_taxonomies();
113
114 if ( $taxes ) {
115 foreach ( $taxes as $woo_tax ) {
116 $tax = WCTaxonomies::TAXONOMY_PREFIX_ATTRIBUTE . $woo_tax->attribute_name;
117 $meta_key = 'order_' . $tax;
118 $terms = get_terms( $tax );
119 if ( $terms ) {
120 foreach ( $terms as $term ) {
121 $term_order = get_term_meta( $term->term_id, $meta_key, true );
122 $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $tax );
123 $translations = $this->sitepress->get_element_translations( $trid, 'tax_' . $tax );
124 if ( $translations ) {
125 foreach ( $translations as $trans ) {
126 if ( $trans->language_code != $lang ) {
127 update_term_meta( $trans->term_id, $meta_key, $term_order );
128 }
129 }
130 }
131 }
132 }
133 }
134 }
135
136 $terms = get_terms( WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY );
137 if ( $terms ) {
138 foreach ( $terms as $term ) {
139 $term_order = get_term_meta( $term->term_id, 'order', true );
140 $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
141 $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
142 if ( $translations ) {
143 foreach ( $translations as $trans ) {
144 if ( $trans->language_code != $lang ) {
145 update_term_meta( $trans->term_id, 'order', $term_order );
146 }
147 }
148 }
149 }
150 }
151
152 $this->sitepress->switch_lang( $cur_lang );
153
154 $this->woocommerce_wpml->settings['is_term_order_synced'] = 'yes';
155 $this->woocommerce_wpml->update_settings();
156
157 }
158
159 public function sync_term_order( $meta_id, $object_id, $meta_key, $meta_value ) {
160 remove_action( 'update_term_meta', [ $this, 'sync_term_order' ], 100 );
161
162 $wc_before_term_meta = get_option( 'db_version' ) < 34370;
163
164 if ( ! isset( $_POST['thetaxonomy'] ) || ! taxonomy_exists( $_POST['thetaxonomy'] ) || ! WCTaxonomies::isProductCategoryOrAttribute( $_POST['thetaxonomy'] ) || substr( $meta_key, 0, 5 ) !== 'order' ) {
165 return;
166 }
167 $tax = filter_input( INPUT_POST, 'thetaxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
168
169 $term_taxonomy_id = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $object_id, $tax ) );
170 $trid = $this->sitepress->get_element_trid( $term_taxonomy_id, 'tax_' . $tax );
171 $translations = $this->sitepress->get_element_translations( $trid, 'tax_' . $tax );
172 if ( $translations ) {
173 foreach ( $translations as $trans ) {
174 if ( $trans->element_id !== $term_taxonomy_id ) {
175
176 if ( $wc_before_term_meta ) {
177 $this->wpdb->update(
178 $this->wpdb->prefix . 'woocommerce_termmeta',
179 [ 'meta_value' => $meta_value ],
180 [
181 'woocommerce_term_id' => $trans->term_id,
182 'meta_key' => $meta_key,
183 ]
184 );
185 } else {
186 update_term_meta( $trans->term_id, $meta_key, $meta_value );
187 }
188 }
189 }
190 }
191
192 add_action( 'update_term_meta', [ $this, 'sync_term_order' ], 100, 4 );
193
194 }
195
196 public function translated_terms_status_update( $term_id, $tt_id, $taxonomy ) {
197
198 if ( isset( $_POST['product_cat_thumbnail_id'] ) || isset( $_POST['display_type'] ) ) {
199 if ( $this->is_original_category( $tt_id, 'tax_' . $taxonomy ) ) {
200 $trid = $this->sitepress->get_element_trid( $tt_id, 'tax_' . $taxonomy );
201 $translations = $this->sitepress->get_element_translations( $trid, 'tax_' . $taxonomy );
202
203 foreach ( $translations as $translation ) {
204 if ( ! $translation->original ) {
205 if ( isset( $_POST['display_type'] ) ) {
206 update_term_meta( $translation->term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
207 }
208 if ( isset( $_POST['product_cat_thumbnail_id'] ) ) {
209 update_term_meta( $translation->term_id, 'thumbnail_id', apply_filters( 'wpml_object_id', esc_attr( $_POST['product_cat_thumbnail_id'] ), 'attachment', true, $translation->language_code ) );
210 }
211 }
212 }
213 }
214 }
215
216 global $wp_taxonomies;
217
218 if ( in_array( 'product', $wp_taxonomies[ $taxonomy ]->object_type ) || in_array( 'product_variation', $wp_taxonomies[ $taxonomy ]->object_type ) ) {
219 $this->update_terms_translated_status( $taxonomy );
220 }
221
222 }
223
224 public function is_original_category( $tt_id, $taxonomy ) {
225 $is_original = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT source_language_code IS NULL FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $tt_id, $taxonomy ) );
226 return (bool) $is_original;
227 }
228
229 public function update_terms_translated_status( $taxonomy ) {
230
231 $wcml_settings = $this->woocommerce_wpml->get_settings();
232 $is_translatable = 1;
233 $not_translated_count = 0;
234 $original_terms = [];
235
236 if ( isset( $wcml_settings['attributes_settings'][ $taxonomy ] ) && ! $wcml_settings['attributes_settings'][ $taxonomy ] ) {
237 $is_translatable = 0;
238 }
239
240 if ( $is_translatable ) {
241
242 $active_languages = $this->sitepress->get_active_languages();
243
244 foreach ( $active_languages as $language ) {
245 $terms = $this->wpdb->get_results(
246 $this->wpdb->prepare(
247 "
248 SELECT t1.element_id AS e1, t2.element_id AS e2 FROM {$this->wpdb->term_taxonomy} x
249 JOIN {$this->wpdb->prefix}icl_translations t1 ON x.term_taxonomy_id = t1.element_id AND t1.element_type = %s AND t1.source_language_code IS NULL
250 LEFT JOIN {$this->wpdb->prefix}icl_translations t2 ON t2.trid = t1.trid AND t2.language_code = %s
251 ",
252 'tax_' . $taxonomy,
253 $language['code']
254 )
255 );
256 foreach ( $terms as $term ) {
257 if ( empty( $term->e2 ) && ! in_array( $term->e1, $original_terms ) ) {
258 $original_terms[] = $term->e1;
259 $not_translated_count ++;
260 }
261 }
262 }
263 }
264
265 $status = $not_translated_count ? $this->NEW_TAXONOMY_TERMS : $this->ALL_TAXONOMY_TERMS_TRANSLATED;
266
267 if ( isset( $wcml_settings['untranstaled_terms'][ $taxonomy ] ) && $wcml_settings['untranstaled_terms'][ $taxonomy ] === $this->NEW_TAXONOMY_IGNORED ) {
268 $status = $this->NEW_TAXONOMY_IGNORED;
269 }
270
271 $wcml_settings['untranstaled_terms'][ $taxonomy ] = [
272 'count' => $not_translated_count,
273 'status' => $status,
274 ];
275
276 $this->woocommerce_wpml->update_settings( $wcml_settings );
277
278 return $wcml_settings['untranstaled_terms'][ $taxonomy ];
279
280 }
281
282 public function is_fully_translated( $taxonomy ) {
283
284 $wcml_settings = $this->woocommerce_wpml->get_settings();
285
286 $return = true;
287
288 if ( ! isset( $wcml_settings['untranstaled_terms'][ $taxonomy ] ) ) {
289 $wcml_settings['untranstaled_terms'][ $taxonomy ] = $this->update_terms_translated_status( $taxonomy );
290 }
291
292 if ( $wcml_settings['untranstaled_terms'][ $taxonomy ]['status'] == $this->NEW_TAXONOMY_TERMS ) {
293 $return = false;
294 }
295
296 return $return;
297 }
298
299 public function get_untranslated_terms_number( $taxonomy, $force_update = false ) {
300
301 $wcml_settings = $this->woocommerce_wpml->get_settings();
302
303 if ( $force_update || ! isset( $wcml_settings['untranstaled_terms'][ $taxonomy ] ) ) {
304 $wcml_settings['untranstaled_terms'][ $taxonomy ] = $this->update_terms_translated_status( $taxonomy );
305 }
306
307 return $wcml_settings['untranstaled_terms'][ $taxonomy ]['count'];
308
309 }
310
311 public function set_flag_for_variation_on_attribute_update( $term_id, $tt_id, $taxonomy ) {
312
313 $attribute_taxonomies = wc_get_attribute_taxonomies();
314 foreach ( $attribute_taxonomies as $a ) {
315 $attribute_taxonomies_arr[] = WCTaxonomies::TAXONOMY_PREFIX_ATTRIBUTE . $a->attribute_name;
316 }
317
318 if ( isset( $attribute_taxonomies_arr ) && in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
319
320 $wcml_settings = $this->woocommerce_wpml->get_settings();
321
322 $term_language = $this->sitepress->get_element_language_details( $tt_id, 'tax_' . $taxonomy );
323
324 if ( isset( $term_language->language_code ) && $term_language->language_code != $this->sitepress->get_default_language() ) {
325 $term_id = apply_filters( 'wpml_object_id', $term_id, $taxonomy, false, $this->sitepress->get_default_language() );
326
327 $objects = get_objects_in_term( $term_id, $taxonomy );
328
329 if ( ! isset( $wcml_settings['variations_needed'][ $taxonomy ] ) ) {
330 $wcml_settings['variations_needed'][ $taxonomy ] = 0;
331 }
332 $wcml_settings['variations_needed'][ $taxonomy ] += count( $objects );
333
334 $this->woocommerce_wpml->update_settings( $wcml_settings );
335
336 }
337 }
338
339 }
340
341 public function sync_taxonomy_translations( $html, $taxonomy, $taxonomy_obj ) {
342
343 $is_wcml = is_admin() && $taxonomy && isset( $_GET['page'] ) && \WCML\Utilities\AdminUrl::PAGE_WPML_WCML == $_GET['page'] && isset( $_GET['tab'] );
344 $is_ajax = wp_doing_ajax() && $taxonomy && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_get_terms_and_labels_for_taxonomy_table';
345
346 if ( $is_wcml || $is_ajax ) {
347
348 $sync_tax = new WCML_Sync_Taxonomy( $this->woocommerce_wpml, $taxonomy, $taxonomy_obj );
349 $html = $sync_tax->get_view();
350 }
351
352 return $html;
353 }
354
355 public function wcml_sync_product_variations( $taxonomy ) {
356 $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
357 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wcml_sync_product_variations' ) ) {
358 die( 'Invalid nonce' );
359 }
360
361 $VARIATIONS_THRESHOLD = 20;
362
363 $wcml_settings = $this->woocommerce_wpml->get_settings();
364 $response = [];
365
366 $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
367
368 $languages_processed = intval( $_POST['languages_processed'] );
369
370 $condition = $languages_processed ? '>=' : '>';
371
372 $where = isset( $_POST['last_post_id'] ) && $_POST['last_post_id'] ? ' ID ' . $condition . ' ' . intval( $_POST['last_post_id'] ) . ' AND ' : '';
373
374 $post_ids = $this->wpdb->get_col(
375 $this->wpdb->prepare(
376 "
377 SELECT DISTINCT tr.object_id
378 FROM {$this->wpdb->term_relationships} tr
379 JOIN {$this->wpdb->term_taxonomy} tx on tr.term_taxonomy_id = tx.term_taxonomy_id
380 JOIN {$this->wpdb->posts} p ON tr.object_id = p.ID
381 JOIN {$this->wpdb->prefix}icl_translations t ON t.element_id = p.ID
382 WHERE {$where} tx.taxonomy = %s AND p.post_type = 'product' AND t.element_type='post_product' AND t.source_language_code IS NULL
383 ORDER BY ID ASC
384
385 ",
386 $taxonomy
387 )
388 );
389
390 $variations_processed = 0;
391 $posts_processed = 0;
392
393 if ( $post_ids ) {
394
395 foreach ( $post_ids as $post_id ) {
396 $terms = wp_get_post_terms( $post_id, $taxonomy );
397 $terms_count = count( $terms );
398
399 $trid = $this->sitepress->get_element_trid( $post_id, 'post_product' );
400 $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
401
402 $i = 1;
403
404 foreach ( $translations as $translation ) {
405
406 if ( $i > $languages_processed && $translation->element_id != $post_id ) {
407 $this->woocommerce_wpml->sync_product_data->sync_product_taxonomies( $post_id, $translation->element_id, $translation->language_code );
408 $this->woocommerce_wpml->sync_variations_data->sync_product_variations( $post_id, $translation->element_id, $translation->language_code, [ 'is_troubleshooting' => true ] );
409 $this->woocommerce_wpml->translation_editor->create_product_translation_package( $post_id, $trid, $translation->language_code, ICL_TM_COMPLETE );
410 $variations_processed += $terms_count * 2;
411 $response['languages_processed'] = $i;
412 $i++;
413 if ( $variations_processed >= $VARIATIONS_THRESHOLD ) {
414 break;
415 }
416 } else {
417 $i++;
418 }
419 }
420 $response['last_post_id'] = $post_id;
421 if ( --$i == count( $translations ) ) {
422 $response['languages_processed'] = 0;
423 $languages_processed = 0;
424 } else {
425 break;
426 }
427
428 $posts_processed ++;
429
430 }
431
432 $response['go'] = 1;
433
434 } else {
435
436 $response['go'] = 0;
437
438 }
439
440
441 $response['progress'] = $response['go'] ? sprintf(
442 /* translators: %d is a number of products */
443 __( '%d products left', 'woocommerce-multilingual' ),
444 count( $post_ids ) - $posts_processed
445 )
446 : __( 'Synchronization complete!', 'woocommerce-multilingual' );
447
448 if ( $response['go'] && isset( $wcml_settings['variations_needed'][ $taxonomy ] ) && ! empty( $variations_processed ) ) {
449 $wcml_settings['variations_needed'][ $taxonomy ] = max( $wcml_settings['variations_needed'][ $taxonomy ] - $variations_processed, 0 );
450 } else {
451 if ( $response['go'] == 0 ) {
452 $wcml_settings['variations_needed'][ $taxonomy ] = 0;
453 }
454 }
455 $wcml_settings['sync_variations'] = 0;
456
457 $this->woocommerce_wpml->update_settings( $wcml_settings );
458
459 echo json_encode( $response );
460 exit;
461 }
462
463 public function wcml_sync_taxonomies_in_content_preview() {
464 $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
465 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wcml_sync_taxonomies_in_content_preview' ) ) {
466 die( 'Invalid nonce' );
467 }
468
469 global $wp_taxonomies;
470
471 $html = $message = $errors = '';
472
473 if ( isset( $wp_taxonomies[ $_POST['taxonomy'] ] ) ) {
474 $object_types = $wp_taxonomies[ $_POST['taxonomy'] ]->object_type;
475
476 foreach ( $object_types as $object_type ) {
477
478 $html .= $this->render_assignment_status( $object_type, $_POST['taxonomy'] );
479
480 }
481 } else {
482 $errors = sprintf(
483 /* translators: %s is a taxonomy name */
484 __( 'Invalid taxonomy %s', 'woocommerce-multilingual' ),
485 $_POST['taxonomy']
486 );
487 }
488
489 echo json_encode(
490 [
491 'html' => $html,
492 'message' => $message,
493 'errors' => $errors,
494 ]
495 );
496 exit;
497 }
498
499 public function wcml_sync_taxonomies_in_content() {
500 $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
501 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wcml_sync_taxonomies_in_content' ) ) {
502 die( 'Invalid nonce' );
503 }
504
505 global $wp_taxonomies;
506
507 $html = $errors = '';
508
509 if ( isset( $wp_taxonomies[ $_POST['taxonomy'] ] ) ) {
510 $html .= $this->render_assignment_status( $_POST['post'], $_POST['taxonomy'], false );
511
512 } else {
513 $errors .= sprintf(
514 /* translators: %s is a taxonomy name */
515 __( 'Invalid taxonomy %s', 'woocommerce-multilingual' ),
516 $_POST['taxonomy']
517 );
518 }
519
520 echo json_encode(
521 [
522 'html' => $html,
523 'errors' => $errors,
524 ]
525 );
526 exit;
527 }
528
529 public function render_assignment_status( $object_type, $taxonomy, $preview = true ) {
530 global $wp_post_types, $wp_taxonomies;
531
532 $default_language = $this->sitepress->get_default_language();
533 $is_taxonomy_translatable = $this->is_translatable_wc_taxonomy( $taxonomy );
534
535 $posts = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} AS p LEFT JOIN {$this->wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = %s AND tr.source_language_code is NULL", $object_type ) );
536
537 foreach ( $posts as $post ) {
538
539 $terms = wp_get_post_terms( $post->ID, $taxonomy );
540
541 $term_ids = [];
542 foreach ( $terms as $term ) {
543 $term_ids[] = $term->term_id;
544 }
545
546 $trid = $this->sitepress->get_element_trid( $post->ID, 'post_' . $post->post_type );
547 $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type, true, true );
548
549 foreach ( $translations as $language => $translation ) {
550
551 if ( $language != $default_language && $translation->element_id ) {
552
553 $terms_of_translation = wp_get_post_terms( $translation->element_id, $taxonomy );
554
555 $translation_term_ids = [];
556 foreach ( $terms_of_translation as $term ) {
557
558 $term_id_original = apply_filters( 'wpml_object_id', $term->term_id, $taxonomy, false, $default_language );
559 if ( ! $term_id_original || ! in_array( $term_id_original, $term_ids ) ) {
560 if ( $preview ) {
561 $needs_sync = true;
562 break( 3 );
563 }
564
565 $current_terms = wp_get_post_terms( $translation->element_id, $taxonomy );
566 $updated_terms = [];
567 foreach ( $current_terms as $cterm ) {
568 if ( $cterm->term_id != $term->term_id ) {
569 $updated_terms[] = $is_taxonomy_translatable ? $term->term_id : $term->name;
570 }
571 {
572
573 if ( $is_taxonomy_translatable && ! is_taxonomy_hierarchical( $taxonomy ) ) {
574 $updated_terms = array_unique( array_map( 'intval', $updated_terms ) );
575 }
576
577 wp_set_post_terms( $translation->element_id, $updated_terms, $taxonomy );
578 }
579 }
580 } else {
581 $translation_term_ids[] = $term_id_original;
582 }
583 }
584
585 foreach ( $term_ids as $term_id ) {
586
587 if ( ! in_array( $term_id, $translation_term_ids ) ) {
588 if ( $preview ) {
589 $needs_sync = true;
590 break( 3 );
591 }
592 $terms_array = [];
593 $term_id_translated = apply_filters( 'wpml_object_id', $term_id, $taxonomy, false, $language );
594
595 $translated_term = $this->wpdb->get_row(
596 $this->wpdb->prepare(
597 "
598 SELECT * FROM {$this->wpdb->terms} t JOIN {$this->wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s",
599 $term_id_translated,
600 $taxonomy
601 )
602 );
603
604 if ( is_object( $translated_term ) ) {
605 $terms_array[] = $translated_term->term_id;
606 }
607 {
608
609 if ( $is_taxonomy_translatable && ! is_taxonomy_hierarchical( $taxonomy ) ) {
610 $terms_array = array_unique( array_map( 'intval', $terms_array ) );
611 }
612
613 wp_set_post_terms( $translation->element_id, $terms_array, $taxonomy, true );
614 }
615 }
616 }
617 }
618 }
619 }
620
621 $wcml_settings = $this->woocommerce_wpml->get_settings();
622 $wcml_settings[ 'sync_' . $taxonomy ] = 0;
623 $this->woocommerce_wpml->update_settings( $wcml_settings );
624
625 $out = '';
626
627 if ( $preview ) {
628
629 $out .= '<div class="wcml_tt_sync_row">';
630 if ( ! empty( $needs_sync ) ) {
631 $out .= '<form class="wcml_tt_do_sync">';
632 $out .= '<input type="hidden" name="post" value="' . $object_type . '" />';
633 $out .= wp_nonce_field( 'wcml_sync_taxonomies_in_content', 'wcml_sync_taxonomies_in_content_nonce', true, false );
634 $out .= '<input type="hidden" name="taxonomy" value="' . $taxonomy . '" />';
635 $out .= sprintf(
636 /* translators: %%1$s is a post type name and %2$s is a taxonomy name */
637 __( 'Some translated %1$s have different %2$s assignments.', 'woocommerce-multilingual' ),
638 '<strong>' . mb_strtolower( $wp_post_types[ $object_type ]->labels->name ) . '</strong>',
639 '<strong>' . mb_strtolower( $wp_taxonomies[ $taxonomy ]->labels->name ) . '</strong>'
640 );
641 $out .= '&nbsp;<a class="submit button-secondary" href="#">' . sprintf(
642 /* translators: %%1$s is a taxonomy name and %2$s is a post type name */
643 __( 'Update %1$s for all translated %2$s', 'woocommerce-multilingual' ),
644 '<strong>' . mb_strtolower( $wp_taxonomies[ $taxonomy ]->labels->name ) . '</strong>',
645 '<strong>' . mb_strtolower( $wp_post_types[ $object_type ]->labels->name ) . '</strong>'
646 ) . '</a>' .
647 '&nbsp;<img src="' . \WCML\functions\assetLink( '/res/img/ajax-loader.gif' ) . '" alt="loading" height="16" width="16" class="wcml_tt_spinner" />';
648 $out .= '</form>';
649 } else {
650 $out .= sprintf(
651 /* translators: %1$s is a taxonomy name and %2$s is a post type name */
652 __( 'All %1$s have the same %2$s assignments.', 'woocommerce-multilingual' ),
653 '<strong>' . mb_strtolower( $wp_taxonomies[ $taxonomy ]->labels->name ) . '</strong>',
654 '<strong>' . mb_strtolower( $wp_post_types[ $object_type ]->labels->name ) . '</strong>'
655 );
656 }
657 $out .= '</div>';
658
659 } else {
660 $out .= sprintf(
661 /* translators: %1$s is a taxonomy name and %2$s is a post type name */
662 __( 'Successfully updated %1$s for all translated %2$s.', 'woocommerce-multilingual' ),
663 $wp_taxonomies[ $taxonomy ]->labels->name,
664 $wp_post_types[ $object_type ]->labels->name
665 );
666
667 }
668
669 return $out;
670 }
671
672 public function shipping_terms( $terms, $post_id, $taxonomy ) {
673 global $pagenow;
674
675 if (
676 'post.php' === $pagenow ||
677 self::PRODUCT_SHIPPING_CLASS !== $taxonomy ||
678 ( isset( $_POST['action'] ) && 'woocommerce_load_variations' === $_POST['action'] ) ) {
679 return $terms;
680 }
681
682 $post_type = get_post_type( $post_id );
683 if ( ! in_array( $post_type, [ 'product', 'product_variation' ], true ) ) {
684 return $terms;
685 }
686
687 $current_language = $this->sitepress->get_current_language();
688 $key = md5( wp_json_encode( [ $post_id, $current_language ] ) );
689 $found = false;
690 $terms = WPML_Non_Persistent_Cache::get( $key, __CLASS__, $found );
691 if ( ! $found ) {
692 remove_filter( 'get_the_terms', [ $this, 'shipping_terms' ], 10 );
693 $terms = get_the_terms(
694 apply_filters( 'wpml_object_id', $post_id, $post_type, true, $current_language ),
695 self::PRODUCT_SHIPPING_CLASS
696 );
697 add_filter( 'get_the_terms', [ $this, 'shipping_terms' ], 10, 3 );
698 WPML_Non_Persistent_Cache::set( $key, $terms, __CLASS__ );
699 }
700
701 return $terms;
702 }
703
704 public function filter_shipping_classes_terms( $terms, $taxonomies, $args ) {
705
706 if ( $taxonomies && is_admin() && in_array( self::PRODUCT_SHIPPING_CLASS, $taxonomies ) ) {
707 $on_wc_settings_page = isset( $_GET['page'] ) && \WCML\Utilities\AdminUrl::PAGE_WOO_SETTINGS === $_GET['page'];
708 $on_shipping_tab = isset( $_GET['tab'] ) && $_GET['tab'] === 'shipping';
709 $on_classes_section = isset( $_GET['section'] ) && $_GET['section'] === 'classes';
710
711 if ( $on_wc_settings_page && $on_shipping_tab && ! $on_classes_section ) {
712 remove_filter( 'get_terms', [ $this, 'filter_shipping_classes_terms' ] );
713 $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
714 $terms = get_terms( $args );
715 add_filter( 'get_terms', [ $this, 'filter_shipping_classes_terms' ], 10, 3 );
716 $this->sitepress->switch_lang();
717 }
718 }
719
720 return $terms;
721 }
722
723 public function wcml_delete_term( $term, $tt_id, $taxonomy, $deleted_term ) {
724 global $wp_taxonomies;
725
726 foreach ( $wp_taxonomies as $key => $taxonomy_obj ) {
727 if ( ( in_array( 'product', $taxonomy_obj->object_type ) || in_array( 'product_variation', $taxonomy_obj->object_type ) ) && $key == $taxonomy ) {
728 $this->update_terms_translated_status( $taxonomy );
729 break;
730 }
731 }
732
733 }
734
735 public function get_product_terms_filter( $terms, $product_id, $taxonomy, $args ) {
736
737 $language = $this->sitepress->get_language_for_element( $product_id, 'post_' . get_post_type( $product_id ) );
738
739 $is_objects_array = is_object( current( $terms ) );
740
741 $filtered_terms = [];
742
743 foreach ( $terms as $term ) {
744
745 if ( ! $is_objects_array ) {
746 $term_obj = get_term_by( 'name', $term, $taxonomy );
747
748 $is_wc_filtering_by_slug = isset( $args['fields'] ) && in_array( $args['fields'], [ 'id=>slug', 'slugs' ] );
749 if ( $is_wc_filtering_by_slug || ! $term_obj ) {
750 $term_obj = get_term_by( 'slug', $term, $taxonomy );
751 $is_slug = true;
752 }
753 }
754
755 if ( empty( $term_obj ) ) {
756 $filtered_terms[] = $term;
757 continue;
758 }
759
760 $trnsl_term_id = apply_filters( 'wpml_object_id', $term_obj->term_id, $taxonomy, true, $language );
761
762 if ( $is_objects_array ) {
763 $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy );
764 } else {
765 if ( isset( $is_slug ) ) {
766 $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy )->slug;
767 } else {
768 $filtered_terms[] = ( wp_doing_ajax() && isset( $_POST['action'] ) && in_array(
769 $_POST['action'],
770 [
771 'woocommerce_add_variation',
772 'woocommerce_link_all_variations',
773 ]
774 ) ) ? strtolower( get_term( $trnsl_term_id, $taxonomy )->name ) : get_term( $trnsl_term_id, $taxonomy )->name;
775 }
776 }
777 }
778
779 return $filtered_terms;
780 }
781
782 public function set_flag_to_sync( $taxonomy, $el_id, $language_code ) {
783 if ( $el_id ) {
784 $elem_details = $this->sitepress->get_element_language_details( $el_id, 'tax_' . $taxonomy );
785 if ( null !== $elem_details->source_language_code ) {
786 $this->check_if_sync_term_translation_needed( $el_id, $taxonomy );
787 }
788 }
789 }
790
791 public function check_if_sync_terms_needed() {
792
793 $wcml_settings = $this->woocommerce_wpml->get_settings();
794 $wcml_settings['sync_variations'] = 0;
795 $wcml_settings['sync_product_cat'] = 0;
796 $wcml_settings['sync_product_tag'] = 0;
797 $wcml_settings['sync_product_shipping_class'] = 0;
798 $this->woocommerce_wpml->update_settings( $wcml_settings );
799
800 $taxonomies_to_check = [ WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY, WCTaxonomies::TAXONOMY_PRODUCT_TAG, self::PRODUCT_SHIPPING_CLASS ];
801
802 foreach ( $taxonomies_to_check as $check_taxonomy ) {
803 $terms = get_terms(
804 $check_taxonomy,
805 [ 'hide_empty' => false ]
806 );
807 if ( is_array( $terms ) ) {
808 foreach ( $terms as $term ) {
809 if ( $this->check_if_sync_term_translation_needed( $term->term_taxonomy_id, $check_taxonomy ) ) {
810 break;
811 }
812 }
813 }
814 }
815
816 $attribute_taxonomies = wc_get_attribute_taxonomies();
817 $flag_set = false;
818 foreach ( $attribute_taxonomies as $a ) {
819
820 $terms = get_terms(
821 WCTaxonomies::TAXONOMY_PREFIX_ATTRIBUTE . $a->attribute_name,
822 [ 'hide_empty' => false ]
823 );
824 if ( is_array( $terms ) ) {
825 foreach ( $terms as $term ) {
826 $flag_set = $this->check_if_sync_term_translation_needed( $term->term_taxonomy_id, WCTaxonomies::TAXONOMY_PREFIX_ATTRIBUTE . $a->attribute_name );
827 if ( $flag_set ) {
828 break;
829 }
830 }
831 }
832
833 if ( $flag_set ) {
834 break;
835 }
836 }
837
838 }
839
840 public function check_if_sync_term_translation_needed( $t_id, $taxonomy ) {
841
842 $wcml_settings = $this->woocommerce_wpml->get_settings();
843
844 $attribute_taxonomies = wc_get_attribute_taxonomies();
845 $attribute_taxonomies_arr = [];
846 foreach ( $attribute_taxonomies as $a ) {
847 $attribute_taxonomies_arr[] = WCTaxonomies::TAXONOMY_PREFIX_ATTRIBUTE . $a->attribute_name;
848 }
849
850 if ( ( isset( $wcml_settings[ 'sync_' . $taxonomy ] ) && $wcml_settings[ 'sync_' . $taxonomy ] ) || ( in_array( $taxonomy, $attribute_taxonomies_arr ) && isset( $wcml_settings['sync_variations'] ) && $wcml_settings['sync_variations'] ) ) {
851 return true;
852 }
853
854 $translations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT t2.element_id, t2.source_language_code FROM {$this->wpdb->prefix}icl_translations AS t1 LEFT JOIN {$this->wpdb->prefix}icl_translations AS t2 ON t1.trid = t2.trid WHERE t1.element_id = %d AND t1.element_type = %s ", $t_id, 'tax_' . $taxonomy ) );
855
856 foreach ( $translations as $key => $translation ) {
857 if ( is_null( $translation->source_language_code ) ) {
858 $original_count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
859 unset( $translations[ $key ] );
860 }
861 }
862
863 foreach ( $translations as $translation ) {
864
865 $count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
866 if ( isset( $original_count ) && $original_count != $count ) {
867
868 if ( in_array( $taxonomy, [ WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY, WCTaxonomies::TAXONOMY_PRODUCT_TAG, self::PRODUCT_SHIPPING_CLASS ] ) ) {
869 $wcml_settings[ 'sync_' . $taxonomy ] = 1;
870 $this->woocommerce_wpml->update_settings( $wcml_settings );
871 return true;
872 }
873
874 if ( in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
875 $wcml_settings['sync_variations'] = 1;
876 $this->woocommerce_wpml->update_settings( $wcml_settings );
877 return true;
878 }
879 }
880 }
881
882 }
883
884 public function get_table_taxonomies( $taxonomies ) {
885
886 foreach ( $taxonomies as $key => $taxonomy ) {
887 if ( ! WCTaxonomies::isProductAttribute( $key ) ) {
888 unset( $taxonomies[ $key ] );
889 }
890 }
891
892 return $taxonomies;
893 }
894
895 public function get_wc_taxonomies() {
896
897 global $wp_taxonomies;
898 $taxonomies = [];
899
900 foreach ( $wp_taxonomies as $key => $taxonomy ) {
901
902 if (
903 ( in_array( 'product', $taxonomy->object_type ) || in_array( 'product_variation', $taxonomy->object_type ) ) &&
904 ! in_array( $key, $taxonomies )
905 ) {
906
907 if ( WCTaxonomies::isProductAttribute( $key ) && ! $this->woocommerce_wpml->attributes->is_translatable_attribute( $key ) ) {
908 continue;
909 }
910
911 $taxonomies[] = $key;
912 }
913 }
914
915 return $taxonomies;
916
917 }
918
919 public function has_wc_taxonomies_to_translate() {
920
921 $taxonomies = $this->get_wc_taxonomies();
922
923 $no_tax_to_trnls = false;
924 foreach ( $taxonomies as $taxonomy ) {
925
926 $is_fully_translated = 0 === $this->get_untranslated_terms_number( $taxonomy );
927 if (
928 ! $this->is_translatable_wc_taxonomy( $taxonomy ) ||
929 $is_fully_translated
930 ) {
931 continue;
932 } else {
933 $no_tax_to_trnls = true;
934 }
935 }
936
937 return $no_tax_to_trnls;
938
939 }
940
941 public function wcml_get_term_id_by_slug( $taxonomy, $slug ) {
942 return $this->wpdb->get_var(
943 $this->wpdb->prepare(
944 "SELECT tt.term_id FROM {$this->wpdb->terms} AS t
945 INNER JOIN {$this->wpdb->term_taxonomy} AS tt
946 ON t.term_id = tt.term_id
947 WHERE tt.taxonomy = %s AND t.slug = %s LIMIT 1",
948 $taxonomy,
949 sanitize_title( $slug )
950 )
951 );
952 }
953
954 public function wcml_get_term_by_id( $term_id, $taxonomy ) {
955 return $this->wpdb->get_row(
956 $this->wpdb->prepare(
957 "
958 SELECT * FROM {$this->wpdb->terms} t
959 JOIN {$this->wpdb->term_taxonomy} x
960 ON x.term_id = t.term_id
961 WHERE t.term_id = %d AND x.taxonomy = %s",
962 $term_id,
963 $taxonomy
964 )
965 );
966 }
967
968 public function wcml_get_term_by_taxonomy_id( $term_taxonomy_id, $taxonomy ) {
969 return $this->wpdb->get_row(
970 $this->wpdb->prepare(
971 "
972 SELECT * FROM {$this->wpdb->terms} t
973 JOIN {$this->wpdb->term_taxonomy} x
974 ON x.term_id = t.term_id
975 WHERE x.term_taxonomy_id = %d AND x.taxonomy = %s",
976 $term_taxonomy_id,
977 $taxonomy
978 )
979 );
980 }
981
982 public function wcml_get_term_by_slug( $slug, $taxonomy ) {
983 return $this->wpdb->get_row(
984 $this->wpdb->prepare(
985 "
986 SELECT * FROM {$this->wpdb->terms} t
987 JOIN {$this->wpdb->term_taxonomy} x
988 ON x.term_id = t.term_id
989 WHERE t.slug = %s AND x.taxonomy = %s LIMIT 1",
990 $slug,
991 $taxonomy
992 )
993 );
994 }
995
996 public function wcml_get_translated_term( $term_id, $taxonomy, $language ) {
997
998 $tr_id = apply_filters( 'wpml_object_id', $term_id, $taxonomy, false, $language );
999
1000 if ( ! is_null( $tr_id ) ) {
1001 $term_id = $tr_id;
1002 }
1003
1004 return $this->wcml_get_term_by_id( $term_id, $taxonomy );
1005 }
1006
1007 public function is_translatable_wc_taxonomy( $taxonomy ) {
1008 if ( in_array( $taxonomy, [ 'product_type', 'product_visibility' ], true ) ) {
1009 return false;
1010 }
1011
1012 return true;
1013 }
1014
1015 public function pre_option_default_product_cat() {
1016
1017 $lang = $this->sitepress->get_current_language();
1018
1019 $lang = $lang === 'all' ? $this->sitepress->get_default_language() : $lang;
1020 $wcml_settings = $this->woocommerce_wpml->get_settings();
1021 $ttid = isset( $wcml_settings['default_categories'][ $lang ] ) ? (int) $wcml_settings['default_categories'][ $lang ] : 0;
1022
1023 return $ttid === 0
1024 ? false : $this->wpdb->get_var(
1025 $this->wpdb->prepare(
1026 "SELECT term_id
1027 FROM {$this->wpdb->term_taxonomy}
1028 WHERE term_taxonomy_id= %d
1029 AND taxonomy='product_cat'",
1030 $ttid
1031 )
1032 );
1033 }
1034
1035 public function update_option_default_product_cat( $oldvalue, $new_value ) {
1036 $new_value = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE taxonomy='product_cat' AND term_id=%d", $new_value ) );
1037 $translations = $this->sitepress->get_element_translations( $this->sitepress->get_element_trid( $new_value, 'tax_product_cat' ) );
1038 $wcml_settings = $this->woocommerce_wpml->get_settings();
1039
1040 if ( ! empty( $translations ) ) {
1041 foreach ( $translations as $t ) {
1042 $wcml_settings['default_categories'][ $t->language_code ] = $t->element_id;
1043 }
1044 if ( isset( $wcml_settings ) ) {
1045 $this->woocommerce_wpml->update_settings( $wcml_settings );
1046 }
1047 }
1048 }
1049
1050 public function add_lang_parameter_to_cache_key( $key ) {
1051 return $key . '-' . $this->sitepress->get_current_language();
1052 }
1053
1054 public function flush_term_cache_added_by_wc_and_wcml( $ids, $taxonomy ) {
1055 if ( 'product_cat' === $taxonomy ) {
1056 $ids = is_array( $ids ) ? $ids : [ $ids ];
1057
1058 $clear_ids = [ 0 ];
1059
1060 foreach ( $ids as $id ) {
1061 $clear_ids[] = $id;
1062 $clear_ids = array_merge( $clear_ids, get_ancestors( $id, 'product_cat', 'taxonomy' ) );
1063 }
1064
1065 $clear_ids = array_unique( $clear_ids );
1066
1067 $lang = apply_filters( 'wpml_current_language', null );
1068
1069 foreach ( $clear_ids as $id ) {
1070 wp_cache_delete( "product-category-hierarchy-{$id}-{$lang}", 'product_cat' );
1071 }
1072 }
1073 }
1074
1075 public static function wpml_is_product_shipping_class_set_as_translated() {
1076 return apply_filters( 'wpml_is_translated_taxonomy', false, self::PRODUCT_SHIPPING_CLASS );
1077 }
1078 }
1079