class-wcml-downloadable-products.php
1 month ago
class-wcml-editor-save-filters.php
1 month ago
class-wcml-editor-ui-product-job.php
1 month ago
class-wcml-editor-ui-wysiwyg-field.php
5 years ago
class-wcml-page-builders.php
1 month ago
class-wcml-synchronize-product-data.php
1 month ago
class-wcml-synchronize-variations-data.php
1 month ago
class-wcml-translation-editor.php
1 month ago
class-wcml-wc-admin-duplicate-product.php
1 month ago
class-wcml-synchronize-product-data.php
512 lines
| 1 | <?php |
| 2 | |
| 3 | use WCML\Terms\SuspendWpmlFiltersFactory; |
| 4 | use WCML\Utilities\DB; |
| 5 | use WCML\Utilities\SyncHash; |
| 6 | use function WCML\functions\isCli; |
| 7 | |
| 8 | class WCML_Synchronize_Product_Data { |
| 9 | |
| 10 | const CUSTOM_FIELD_KEY_SEPARATOR = ':::'; |
| 11 | |
| 12 | const PRIORITY_BEFORE_STOCK_EMAIL_TRIGGER = 9; |
| 13 | |
| 14 | private $woocommerce_wpml; |
| 15 | private $sitepress; |
| 16 | private $post_translations; |
| 17 | private $wpdb; |
| 18 | |
| 19 | public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Post_Translation $post_translations, wpdb $wpdb ) { |
| 20 | $this->woocommerce_wpml = $woocommerce_wpml; |
| 21 | $this->sitepress = $sitepress; |
| 22 | $this->post_translations = $post_translations; |
| 23 | $this->wpdb = $wpdb; |
| 24 | } |
| 25 | |
| 26 | public function add_hooks() { |
| 27 | if ( is_admin() || isCli() ) { |
| 28 | add_action( 'deleted_term_relationships', [ $this, 'delete_term_relationships_update_term_count' ], 10, 2 ); |
| 29 | } |
| 30 | |
| 31 | add_action( 'woocommerce_product_set_visibility', [ $this, 'sync_product_translations_visibility' ] ); |
| 32 | |
| 33 | add_action( 'woocommerce_recorded_sales', [ $this, 'sync_product_total_sales' ] ); |
| 34 | |
| 35 | add_action( 'woocommerce_product_set_stock_status', [ $this, 'sync_stock_status_for_translations' ], 100, 2 ); |
| 36 | add_action( 'woocommerce_variation_set_stock_status', [ $this, 'sync_stock_status_for_translations' ], 10, 2 ); |
| 37 | |
| 38 | add_filter( 'future_product', [ $this, 'set_schedule_for_translations' ], 10, 2 ); |
| 39 | } |
| 40 | |
| 41 | public function synchronize_products( $post_id, $post, $force_valid_context = false, $wpRestRequest = null ) { |
| 42 | do_action( \WCML\Synchronization\Hooks::HOOK_SYNCHRONIZE_PRODUCT_TRANSLATIONS, $post, [], [] ); |
| 43 | } |
| 44 | |
| 45 | public function sync_product_data( $original_product_id, $tr_product_id, $lang, $duplicate = false ) { |
| 46 | do_action( \WCML\Synchronization\Hooks::HOOK_SYNCHRONIZE_PRODUCT_TRANSLATIONS, get_post( $original_product_id ), [ $tr_product_id ], [ $tr_product_id => $lang ] ); |
| 47 | } |
| 48 | |
| 49 | public function sync_product_taxonomies( $original_product_id, $tr_product_id, $lang ) { |
| 50 | do_action( \WCML\Synchronization\Hooks::HOOK_SYNCHRONIZE_PRODUCT_COMPONENT, get_post( $original_product_id ), [ $tr_product_id ], [ $tr_product_id => $lang ], \WCML\Synchronization\Store::COMPONENT_TAXONOMIES ); |
| 51 | } |
| 52 | |
| 53 | public function delete_term_relationships_update_term_count( $object_id, $tt_ids ) { |
| 54 | |
| 55 | if ( get_post_type( $object_id ) === 'product' ) { |
| 56 | |
| 57 | $original_product_id = $this->post_translations->get_original_element( $object_id ); |
| 58 | $translations = $this->post_translations->get_element_translations( $original_product_id, false, true ); |
| 59 | |
| 60 | $filtersSuspend = SuspendWpmlFiltersFactory::create(); |
| 61 | foreach ( $translations as $translation ) { |
| 62 | $this->wcml_update_term_count_by_ids( $tt_ids, $this->post_translations->get_element_lang_code( $translation ) ); |
| 63 | } |
| 64 | $filtersSuspend->resume(); |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | |
| 69 | public function wcml_update_term_count_by_ids( $tt_ids, $language, $taxonomy = '', $tr_product_id = false ) { |
| 70 | global $wpml_term_translations; |
| 71 | $tt_ids_trans = []; |
| 72 | |
| 73 | foreach ( $tt_ids as $tt_id ) { |
| 74 | $tt_id_trans = $wpml_term_translations->element_id_in( $tt_id, $language ); |
| 75 | if ( $tt_id_trans ) { |
| 76 | $tt_ids_trans[] = $tt_id_trans; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | $tt_ids_trans = array_values( array_unique( array_map( 'intval', $tt_ids_trans ) ) ); |
| 81 | |
| 82 | if ( empty( $tt_ids_trans ) ) { |
| 83 | return; |
| 84 | } |
| 85 | |
| 86 | if ( in_array( $taxonomy, [ 'product_cat', 'product_tag' ] ) ) { |
| 87 | $this->sitepress->switch_lang( $language ); |
| 88 | wp_update_term_count( $tt_ids_trans, $taxonomy ); |
| 89 | $this->sitepress->switch_lang(); |
| 90 | } |
| 91 | |
| 92 | if ( $tr_product_id ) { |
| 93 | $t_ids = $this->wpdb->get_col( |
| 94 | $this->wpdb->prepare( |
| 95 | "SELECT term_id FROM {$this->wpdb->term_taxonomy} WHERE term_taxonomy_id IN (" . DB::prepareIn( $tt_ids_trans, '%d' ) . ") LIMIT %d", |
| 96 | count( $tt_ids_trans ) |
| 97 | ) |
| 98 | ); |
| 99 | $t_ids = array_unique( array_map( 'intval', $t_ids ) ); |
| 100 | wp_set_post_terms( $tr_product_id, $t_ids, $taxonomy ); |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | public function sync_linked_products( $product_id, $translated_product_id, $lang ) { |
| 105 | |
| 106 | $this->sync_up_sells_products( $product_id, $translated_product_id, $lang ); |
| 107 | $this->sync_cross_sells_products( $product_id, $translated_product_id, $lang ); |
| 108 | $this->sync_grouped_products( $product_id, $translated_product_id, $lang ); |
| 109 | |
| 110 | $translated_product_parent_id = wp_get_post_parent_id( $translated_product_id ); |
| 111 | if ( $translated_product_parent_id ) { |
| 112 | delete_transient( 'wc_product_children_' . $translated_product_parent_id ); |
| 113 | delete_transient( '_transient_wc_product_children_ids_' . $translated_product_parent_id ); |
| 114 | } |
| 115 | |
| 116 | } |
| 117 | |
| 118 | public function sync_up_sells_products( $product_id, $translated_product_id, $lang ) { |
| 119 | |
| 120 | $original_up_sells = maybe_unserialize( get_post_meta( $product_id, '_upsell_ids', true ) ); |
| 121 | $trnsl_up_sells = []; |
| 122 | if ( $original_up_sells ) { |
| 123 | foreach ( $original_up_sells as $original_up_sell_product ) { |
| 124 | $trnsl_up_sells[] = apply_filters( 'wpml_object_id', $original_up_sell_product, get_post_type( $original_up_sell_product ), false, $lang ); |
| 125 | } |
| 126 | } |
| 127 | update_post_meta( $translated_product_id, '_upsell_ids', $trnsl_up_sells ); |
| 128 | |
| 129 | } |
| 130 | |
| 131 | public function sync_cross_sells_products( $product_id, $translated_product_id, $lang ) { |
| 132 | |
| 133 | $original_cross_sells = maybe_unserialize( get_post_meta( $product_id, '_crosssell_ids', true ) ); |
| 134 | $trnsl_cross_sells = []; |
| 135 | if ( $original_cross_sells ) { |
| 136 | foreach ( $original_cross_sells as $original_cross_sell_product ) { |
| 137 | $trnsl_cross_sells[] = apply_filters( 'wpml_object_id', $original_cross_sell_product, get_post_type( $original_cross_sell_product ), false, $lang ); |
| 138 | } |
| 139 | } |
| 140 | update_post_meta( $translated_product_id, '_crosssell_ids', $trnsl_cross_sells ); |
| 141 | |
| 142 | } |
| 143 | |
| 144 | public function sync_grouped_products( $product_id, $translated_product_id, $lang ) { |
| 145 | |
| 146 | $original_children = maybe_unserialize( get_post_meta( $product_id, '_children', true ) ); |
| 147 | $translated_children = []; |
| 148 | if ( $original_children ) { |
| 149 | foreach ( $original_children as $original_children_product ) { |
| 150 | $translated_children[] = apply_filters( 'wpml_object_id', $original_children_product, get_post_type( $original_children_product ), false, $lang ); |
| 151 | } |
| 152 | } |
| 153 | update_post_meta( $translated_product_id, '_children', $translated_children ); |
| 154 | |
| 155 | } |
| 156 | |
| 157 | public function sync_product_stock( $product, $translatedProduct = false ) { |
| 158 | $productId = $product->get_id(); |
| 159 | |
| 160 | if ( $translatedProduct ) { |
| 161 | $translatedProductId = $translatedProduct->get_id(); |
| 162 | $translations = [ $translatedProductId ]; |
| 163 | $translationsLanguages = [ $translatedProductId => $this->post_translations->get_element_lang_code( $translatedProductId ) ]; |
| 164 | } else { |
| 165 | $translations = $this->post_translations->get_element_translations( $productId ); |
| 166 | if ( empty( $translations ) ) { |
| 167 | return; |
| 168 | } |
| 169 | |
| 170 | $translationsLanguages = []; |
| 171 | foreach ( $translations as $index => $translation ) { |
| 172 | if ( $productId === (int) $translation ) { |
| 173 | unset( $translations[ $index ] ); |
| 174 | } else { |
| 175 | $translationsLanguages[ $translation ] = $this->post_translations->get_element_lang_code( $translation ); |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | do_action( \WCML\Synchronization\Hooks::HOOK_SYNCHRONIZE_PRODUCT_COMPONENT, get_post( $productId ), $translations, $translationsLanguages, \WCML\Synchronization\Store::COMPONENT_STOCK ); |
| 181 | } |
| 182 | |
| 183 | public function sync_product_stock_hook( $product ) { |
| 184 | $productId = $product->get_id(); |
| 185 | $translations = $this->post_translations->get_element_translations( $productId ); |
| 186 | if ( empty( $translations ) ) { |
| 187 | return; |
| 188 | } |
| 189 | |
| 190 | $translationsLanguages = []; |
| 191 | foreach ( $translations as $index => $translation ) { |
| 192 | if ( $productId === (int) $translation ) { |
| 193 | unset( $translations[ $index ] ); |
| 194 | } else { |
| 195 | $translationsLanguages[ $translation ] = $this->post_translations->get_element_lang_code( $translation ); |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | do_action( \WCML\Synchronization\Hooks::HOOK_SYNCHRONIZE_PRODUCT_COMPONENT, get_post( $productId ), $translations, $translationsLanguages, \WCML\Synchronization\Store::COMPONENT_STOCK ); |
| 200 | } |
| 201 | |
| 202 | public function sync_product_total_sales( $order_id ) { |
| 203 | |
| 204 | $order = wc_get_order( $order_id ); |
| 205 | |
| 206 | foreach ( $order->get_items() as $item ) { |
| 207 | |
| 208 | if ( $item instanceof WC_Order_Item_Product ) { |
| 209 | $product_id = $item->get_product_id(); |
| 210 | $qty = $item->get_quantity(); |
| 211 | } else { |
| 212 | $product_id = $item['product_id']; |
| 213 | $qty = $item['qty']; |
| 214 | } |
| 215 | |
| 216 | $qty = apply_filters( 'wcml_order_item_quantity', $qty, $order, $item ); |
| 217 | |
| 218 | $data_store = WC_Data_Store::load( 'product' ); |
| 219 | $translations = $this->post_translations->get_element_translations( $product_id ); |
| 220 | foreach ( $translations as $translation ) { |
| 221 | if ( $product_id !== (int) $translation ) { |
| 222 | $data_store->update_product_sales( (int) $translation, absint( $qty ), 'increase' ); |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | public function sync_stock_status_for_translations( $product_id, $status ) { |
| 229 | |
| 230 | if ( $this->woocommerce_wpml->products->is_original_product( $product_id ) ) { |
| 231 | |
| 232 | $translations = $this->post_translations->get_element_translations( $product_id, false, true ); |
| 233 | |
| 234 | foreach ( $translations as $translation ) { |
| 235 | $this->woocommerce_wpml->products->update_stock_status( $translation, $status ); |
| 236 | $this->wc_taxonomies_recount_after_stock_change( $translation ); |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | private function wc_taxonomies_recount_after_stock_change( $product_id ) { |
| 242 | |
| 243 | remove_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1 ); |
| 244 | |
| 245 | wp_cache_delete( $product_id, 'product_cat_relationships' ); |
| 246 | wp_cache_delete( $product_id, 'product_tag_relationships' ); |
| 247 | |
| 248 | wc_recount_after_stock_change( $product_id ); |
| 249 | |
| 250 | add_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1, 1 ); |
| 251 | |
| 252 | } |
| 253 | |
| 254 | public function sync_date_and_parent( $original_product_id, $tr_product_id, $lang ) { |
| 255 | $tr_parent_id = apply_filters( 'wpml_object_id', wp_get_post_parent_id( $original_product_id ), 'product', false, $lang ); |
| 256 | $tr_parent_id = is_null( $tr_parent_id ) ? 0 : (int) $tr_parent_id; |
| 257 | $args = []; |
| 258 | if ( wp_get_post_parent_id( $tr_product_id ) !== $tr_parent_id ) { |
| 259 | $args['post_parent'] = $tr_parent_id; |
| 260 | } |
| 261 | if ( ! empty( $this->woocommerce_wpml->settings['products_sync_date'] ) ) { |
| 262 | $orig_product = get_post( $original_product_id ); |
| 263 | $args['post_date'] = $orig_product->post_date; |
| 264 | } |
| 265 | if ( ! empty( $args ) ) { |
| 266 | $this->wpdb->update( |
| 267 | $this->wpdb->posts, |
| 268 | $args, |
| 269 | [ 'id' => $tr_product_id ] |
| 270 | ); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | public function set_schedule_for_translations( $deprecated, $post ) { |
| 275 | |
| 276 | if ( $this->woocommerce_wpml->products->is_original_product( $post->ID ) ) { |
| 277 | $translations = $this->post_translations->get_element_translations( $post->ID, false, true ); |
| 278 | foreach ( $translations as $translation ) { |
| 279 | wp_clear_scheduled_hook( 'publish_future_post', [ $translation ] ); |
| 280 | wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT' ), 'publish_future_post', [ $translation ] ); |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | public function icl_pro_translation_completed( $tr_product_id ) {} |
| 286 | |
| 287 | public function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ) {} |
| 288 | |
| 289 | public function woocommerce_product_quick_edit_save( $product ) {} |
| 290 | |
| 291 | public function sync_downloadable_files( $originalProductId, $translationId ) { |
| 292 | global $iclTranslationManagement; |
| 293 | $settingFactory = new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement ); |
| 294 | $postmetaFieldSetting = $settingFactory->post_meta_setting( '_downloadable_files' ); |
| 295 | $postmetaFieldStatus = $postmetaFieldSetting->status(); |
| 296 | if ( WPML_IGNORE_CUSTOM_FIELD === $postmetaFieldStatus ) { |
| 297 | return; |
| 298 | } |
| 299 | $this->woocommerce_wpml->downloadable->sync_files_to_translations( $originalProductId, $translationId ); |
| 300 | |
| 301 | self::syncDeletedCustomFields( $originalProductId, $translationId ); |
| 302 | |
| 303 | do_action( 'wcml_after_duplicate_product_post_meta', $originalProductId, $translationId, false ); |
| 304 | } |
| 305 | |
| 306 | public function duplicate_product_post_meta( $original_product_id, $translated_product_id, $data = false ) { |
| 307 | if ( ! $data ) { |
| 308 | $this->sync_downloadable_files( $original_product_id, $translated_product_id ); |
| 309 | $wcml_data_store = wcml_product_data_store_cpt(); |
| 310 | $wcml_data_store->update_lookup_table_data( $translated_product_id ); |
| 311 | return; |
| 312 | } |
| 313 | |
| 314 | global $iclTranslationManagement; |
| 315 | $custom_fields = get_post_custom( $original_product_id ); |
| 316 | $post_fields = null; |
| 317 | $settings_factory = new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement ); |
| 318 | |
| 319 | unset( $custom_fields['_thumbnail_id'] ); |
| 320 | unset( $custom_fields[ SyncHash::META_KEY ] ); |
| 321 | |
| 322 | foreach ( $custom_fields as $key => $meta ) { |
| 323 | $setting = $settings_factory->post_meta_setting( $key ); |
| 324 | |
| 325 | if ( WPML_IGNORE_CUSTOM_FIELD === $setting->status() ) { |
| 326 | continue; |
| 327 | } |
| 328 | |
| 329 | if ( '_downloadable_files' === $key ) { |
| 330 | $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $translated_product_id, $data ); |
| 331 | } elseif ( WPML_TRANSLATE_CUSTOM_FIELD === $setting->status() ) { |
| 332 | $post_fields = $this->sync_custom_field_value( $key, $data, $translated_product_id, $post_fields, $original_product_id ); |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | self::syncDeletedCustomFields( $original_product_id, $translated_product_id ); |
| 337 | |
| 338 | $wcml_data_store = wcml_product_data_store_cpt(); |
| 339 | $wcml_data_store->update_lookup_table_data( $translated_product_id ); |
| 340 | |
| 341 | do_action( 'wcml_after_duplicate_product_post_meta', $original_product_id, $translated_product_id, $data ); |
| 342 | } |
| 343 | |
| 344 | public function sync_custom_field_value( $custom_field, $translation_data, $trnsl_product_id, $post_fields, $original_product_id = false, $is_variation = false ) { |
| 345 | |
| 346 | if ( is_null( $post_fields ) ) { |
| 347 | $post_fields = []; |
| 348 | if ( isset( $_POST['data'] ) && ! is_array( $_POST['data'] ) ) { |
| 349 | $job_data = []; |
| 350 | parse_str( $_POST['data'], $job_data ); |
| 351 | $post_fields = $job_data['fields']; |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | $custom_filed_key = $is_variation && $original_product_id ? $custom_field . $original_product_id : $custom_field; |
| 356 | |
| 357 | if ( isset( $translation_data[ md5( $custom_filed_key ) ] ) ) { |
| 358 | $meta_value = $translation_data[ md5( $custom_filed_key ) ]; |
| 359 | $meta_value = apply_filters( 'wcml_meta_value_before_add', $meta_value, $custom_filed_key ); |
| 360 | update_post_meta( $trnsl_product_id, $custom_field, $meta_value ); |
| 361 | unset( $post_fields[ $custom_filed_key ] ); |
| 362 | } else { |
| 363 | foreach ( $post_fields as $post_field_key => $post_field ) { |
| 364 | |
| 365 | if ( 1 === preg_match( '/field-' . $custom_field . '-.*?/', $post_field_key ) ) { |
| 366 | delete_post_meta( $trnsl_product_id, $custom_field ); |
| 367 | |
| 368 | $custom_fields = get_post_meta( $original_product_id, $custom_field ); |
| 369 | $single = count( $custom_fields ) === 1; |
| 370 | $custom_fields = $single ? $custom_fields[0] : $custom_fields; |
| 371 | |
| 372 | $filtered_custom_fields = array_filter( $custom_fields ); |
| 373 | $custom_fields_values = array_values( $filtered_custom_fields ); |
| 374 | $custom_fields_keys = array_keys( $filtered_custom_fields ); |
| 375 | |
| 376 | foreach ( $custom_fields_values as $custom_field_index => $custom_field_value ) { |
| 377 | $custom_fields_values = |
| 378 | $this->get_translated_custom_field_values( |
| 379 | $custom_fields_values, |
| 380 | $translation_data, |
| 381 | $custom_field, |
| 382 | $custom_field_value, |
| 383 | $custom_field_index |
| 384 | ); |
| 385 | } |
| 386 | |
| 387 | $custom_fields_translated = $custom_fields; |
| 388 | |
| 389 | foreach ( $custom_fields_values as $index => $value ) { |
| 390 | if ( ! $single ) { |
| 391 | add_post_meta( $trnsl_product_id, $custom_field, $value, $single ); |
| 392 | } else { |
| 393 | $custom_fields_translated[ $custom_fields_keys[ $index ] ] = $value; |
| 394 | } |
| 395 | } |
| 396 | if ( $single ) { |
| 397 | update_post_meta( $trnsl_product_id, $custom_field, $custom_fields_translated ); |
| 398 | } |
| 399 | } else { |
| 400 | $meta_value = $translation_data[ md5( $post_field_key ) ]; |
| 401 | $field_key = explode( ':', $post_field_key ); |
| 402 | if ( $field_key[0] == $custom_filed_key ) { |
| 403 | if ( 'new' === substr( $field_key[1], 0, 3 ) ) { |
| 404 | add_post_meta( $trnsl_product_id, $custom_field, $meta_value ); |
| 405 | } else { |
| 406 | update_meta( $field_key[1], $custom_field, $meta_value ); |
| 407 | } |
| 408 | unset( $post_fields[ $post_field_key ] ); |
| 409 | } |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | return $post_fields; |
| 415 | } |
| 416 | |
| 417 | public function get_translated_custom_field_values( $custom_fields_values, $translation_data, $custom_field, $custom_field_value, $custom_field_index ) { |
| 418 | |
| 419 | if ( is_scalar( $custom_field_value ) ) { |
| 420 | $key_index = $custom_field . '-' . $custom_field_index; |
| 421 | $cf = 'field-' . $key_index; |
| 422 | $meta_keys = explode( '-', $custom_field_index ); |
| 423 | $meta_keys = array_map( [ $this, 'replace_separator' ], $meta_keys ); |
| 424 | $custom_fields_values = $this->insert_under_keys( |
| 425 | $meta_keys, |
| 426 | $custom_fields_values, |
| 427 | $translation_data[ md5( $cf ) ] |
| 428 | ); |
| 429 | } else { |
| 430 | foreach ( $custom_field_value as $ind => $value ) { |
| 431 | $field_index = $custom_field_index . '-' . str_replace( '-', self::CUSTOM_FIELD_KEY_SEPARATOR, $ind ); |
| 432 | $custom_fields_values = $this->get_translated_custom_field_values( $custom_fields_values, $translation_data, $custom_field, $value, $field_index ); |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | return $custom_fields_values; |
| 437 | |
| 438 | } |
| 439 | |
| 440 | private function replace_separator( $el ) { |
| 441 | return str_replace( self::CUSTOM_FIELD_KEY_SEPARATOR, '-', $el ); |
| 442 | } |
| 443 | |
| 444 | private function insert_under_keys( $keys, $array, $value ) { |
| 445 | $array[ $keys[0] ] = count( $keys ) === 1 |
| 446 | ? $value |
| 447 | : $this->insert_under_keys( |
| 448 | array_slice( $keys, 1 ), |
| 449 | ( $array[ $keys[0] ] ?? [] ), |
| 450 | $value |
| 451 | ); |
| 452 | |
| 453 | return $array; |
| 454 | } |
| 455 | |
| 456 | public function icl_connect_translations_action() {} |
| 457 | |
| 458 | public function check_if_product_fields_sync_needed( $original_id, $trnsl_post_id, $fields_group ) {} |
| 459 | |
| 460 | public function sync_product_translations_visibility( $product_id ) { |
| 461 | $translations = $this->post_translations->get_element_translations( $product_id, false, true ); |
| 462 | if ( $translations ) { |
| 463 | |
| 464 | $product = wc_get_product( $product_id ); |
| 465 | $terms = []; |
| 466 | |
| 467 | if ( $this->woocommerce_wpml->products->is_original_product( $product_id ) ) { |
| 468 | if ( $product->is_featured() ) { |
| 469 | $terms[] = 'featured'; |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | if ( 'outofstock' === $product->get_stock_status() ) { |
| 474 | $terms[] = 'outofstock'; |
| 475 | } |
| 476 | |
| 477 | $rating = min( 5, round( $product->get_average_rating() ) ); |
| 478 | |
| 479 | if ( $rating > 0 ) { |
| 480 | $terms[] = 'rated-' . $rating; |
| 481 | } |
| 482 | |
| 483 | foreach ( $translations as $translation ) { |
| 484 | if ( $product_id !== (int) $translation ) { |
| 485 | wp_set_post_terms( $translation, $terms, 'product_visibility', false ); |
| 486 | } |
| 487 | } |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | public static function syncDeletedCustomFields( $originalId, $translationId ) { |
| 492 | $settingsFactory = wpml_load_core_tm()->settings_factory(); |
| 493 | |
| 494 | $isCopiedField = function( $field ) use ( $settingsFactory ) { |
| 495 | return WPML_COPY_CUSTOM_FIELD === $settingsFactory->post_meta_setting( $field )->status(); |
| 496 | }; |
| 497 | |
| 498 | $deleteFieldInTranslation = function( $field ) use ( $translationId ) { |
| 499 | delete_post_meta( $translationId, $field ); |
| 500 | }; |
| 501 | |
| 502 | $deletedInOriginal = wpml_collect( array_diff( |
| 503 | array_keys( get_post_custom( $translationId ) ), |
| 504 | array_keys( get_post_custom( $originalId ) ) |
| 505 | ) ); |
| 506 | |
| 507 | $deletedInOriginal |
| 508 | ->filter( $isCopiedField ) |
| 509 | ->map( $deleteFieldInTranslation ); |
| 510 | } |
| 511 | } |
| 512 |