Headline
CVE-2023-4940: bulkoperations.php in woo-bulk-editor/trunk/ext/bulkoperations – WordPress Plugin Repository
The BEAR for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 1.1.3.3. This is due to missing or incorrect nonce validation on the woobe_bulkoperations_swap function. This makes it possible for unauthenticated attackers to manipulate products via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.
1<?php2if (!defined(‘ABSPATH’)) {3 exit; // Exit if accessed directly4}56//any operations with variations only7final class WOOBE_BULKOPERATIONS extends WOOBE_EXT {89 protected $slug = 'bulkoperations’; //unique1011 //protected $is = 'external’;1213 public function __construct() {14 add_action('woobe_ext_scripts’, array($this, ‘woobe_ext_scripts’), 1);15 add_action('woobe_tools_panel_buttons’, array($this, ‘woobe_tools_panel_buttons’), 1);16 add_action('woobe_page_end’, array($this, ‘woobe_page_end’), 1);1718 //ajax19 add_action('wp_ajax_woobe_bulkoperations_get_att_terms’, array($this, ‘woobe_bulkoperations_get_att_terms’), 1);20 add_action('wp_ajax_woobe_bulkoperations_get_possible_combos’, array($this, ‘woobe_bulkoperations_get_possible_combos’), 1);21 add_action('wp_ajax_woobe_bulkoperations_get_prod_count’, array($this, ‘woobe_bulkoperations_get_prod_count’), 1);22 add_action('wp_ajax_woobe_bulkoperations_apply_combinations’, array($this, ‘woobe_bulkoperations_apply_combinations’), 1);23 add_action('wp_ajax_woobe_bulkoperations_apply_default_combination’, array($this, ‘woobe_bulkoperations_apply_default_combination’), 1);24 add_action('wp_ajax_woobe_bulkoperations_get_product_variations’, array($this, ‘woobe_bulkoperations_get_product_variations’), 1);25 add_action('wp_ajax_woobe_bulkoperations_delete’, array($this, ‘woobe_bulkoperations_delete’), 1);26 add_action('wp_ajax_woobe_bulkoperations_ordering’, array($this, ‘woobe_bulkoperations_ordering’), 1);27 add_action('wp_ajax_woobe_bulkoperations_swap’, array($this, ‘woobe_bulkoperations_swap’), 1);28 add_action('wp_ajax_woobe_bulkoperations_attaching’, array($this, ‘woobe_bulkoperations_attaching’), 1);29 add_action('wp_ajax_woobe_bulkoperations_visibility’, array($this, ‘woobe_bulkoperations_visibility’), 1);30 }3132 public function woobe_ext_scripts() {33 wp_enqueue_script(‘woobe_ext_’ . $this->slug, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '.js’, array(), WOOBE_VERSION);34 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-2’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-2.js’, array(), WOOBE_VERSION);35 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-3’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-3.js’, array(), WOOBE_VERSION);36 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-4’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-4.js’, array(), WOOBE_VERSION);37 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-5’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-5.js’, array(), WOOBE_VERSION);38 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-6’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-6.js’, array(), WOOBE_VERSION);39 wp_enqueue_script(‘woobe_ext_’ . $this->slug . '-7’, $this->get_ext_link() . ‘assets/js/’ . $this->slug . '-7.js’, array(), WOOBE_VERSION);40 wp_enqueue_style(‘woobe_ext_’ . $this->slug, $this->get_ext_link() . ‘assets/css/’ . $this->slug . '.css’, array(), WOOBE_VERSION);41 ?>42 <script>43 lang.<?php echo $this->slug ?> = {};44 lang.<?php echo $this->slug ?>.going = '<?php esc_html_e('ATTENTION: Variations Advanced Bulk Operation is going’, ‘woo-bulk-editor’) ?>’;45 lang.<?php echo $this->slug ?>.finished = '<?php esc_html_e('Variations Advanced Bulk Operation is finished’, ‘woo-bulk-editor’) ?>’;46 lang.<?php echo $this->slug ?>.finished2 = '<?php esc_html_e('Attaching of the default combination for the products variations is finished!’, ‘woo-bulk-editor’) ?>’;47 lang.<?php echo $this->slug ?>.finished3 = '<?php esc_html_e('Deleting of the products variations is finished’, ‘woo-bulk-editor’) ?>’;48 lang.<?php echo $this->slug ?>.finished4 = '<?php esc_html_e('Ordering of the products variations is finished’, ‘woo-bulk-editor’) ?>’;49 lang.<?php echo $this->slug ?>.finished5 = '<?php esc_html_e('Swap of variations is finished’, ‘woo-bulk-editor’) ?>’;50 lang.<?php echo $this->slug ?>.finished6 = '<?php esc_html_e('Attaching of the products variations is finished’, ‘woo-bulk-editor’) ?>’;51 lang.<?php echo $this->slug ?>.generating = '<?php esc_html_e('Generating possible combinations’, ‘woo-bulk-editor’) ?>’;52 lang.<?php echo $this->slug ?>.generated = '<?php esc_html_e('Possible combinations been generated.’, ‘woo-bulk-editor’) ?>’;53 lang.<?php echo $this->slug ?>.no_combinations = '<?php esc_html_e('Combination(s) not selected!’, ‘woo-bulk-editor’) ?>’;54 lang.<?php echo $this->slug ?>.not_selected_var = '<?php esc_html_e('variation is not selected’, ‘woo-bulk-editor’) ?>’;55 lang.<?php echo $this->slug ?>.no_vars = '<?php esc_html_e('the product has no variations’, ‘woo-bulk-editor’) ?>’;56 </script>57 <?php58 }5960 public function woobe_tools_panel_buttons() {61 ?>62 <a href="#" class="button button-secondary woobe_tools_panel_newvars_btn" title="<?php esc_html_e('Variations Advanced Bulk Operations’, ‘woo-bulk-editor’) ?>"></a>63 <?php64 }6566 public function woobe_page_end() {67 $data = array();68 $data[‘attributes’] = wc_get_attribute_taxonomies();69 echo WOOBE_HELPER::render_html($this->get_ext_path() . 'views/panel.php’, $data);70 }7172 //ajax73 public function woobe_bulkoperations_get_att_terms() {74 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {75 die(‘0’);76 }77 die(json_encode(WOOBE_HELPER::get_taxonomies_terms_hierarchy(sanitize_text_field($_REQUEST[‘attribute’]))));78 }7980 //ajax81 public function woobe_bulkoperations_get_possible_combos() {82 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {83 die(‘0’);84 } 85 try {86 $res = "";87 if (isset($_REQUEST[‘arrays’])) {88 //no db writing, ajax to DOM89 $res = json_encode($this->generate_combinations($_REQUEST[‘arrays’]));90 }91 } catch (Exception $e) {92 print_r($e);93 }94 die($res);95 }9697 //https://gist.github.com/fabiocicerchia/455689298 private function generate_combinations($data, &$all = array(), array $group = array(), $value = null, $i = 0) {99 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {100 die(‘0’);101 } 102 if (!is_array($data)) {103 $data = array();104 }105 $keys = array_keys($data);106 if (isset($value) === true) {107 array_push($group, intval($value));108 }109110 if ($i >= count($data)) {111 array_push($all, $group);112 } else {113 $currentKey = $keys[$i];114 $currentElement = $data[$currentKey];115 foreach ($currentElement as $val) {116 $this->generate_combinations($data, $all, $group, $val, $i + 1);117 }118 }119120 return $all;121 }122123 //ajax124 public function woobe_bulkoperations_get_prod_count() {125 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {126 die(‘0’);127 }128 if (!current_user_can(‘manage_woocommerce’)) {129 die(‘0’);130 }131132 //***133134 $products = $this->products->gets(array(135 ‘fields’ => 'ids’,136 ‘no_found_rows’ => true137 ));138 echo json_encode($products->posts);139140 exit;141 }142143 //ajax144 public function woobe_bulkoperations_apply_combinations() {145 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {146 die(‘0’);147 }148 if (!isset($_REQUEST[‘products_ids’])) {149 die(‘0’);150 }151152 //***153154 $products_ids = array_map(function($item) {155 return intval($item); //sanitize intval156 }, $_REQUEST[‘products_ids’]);157158 $combinations = WOOBE_HELPER::sanitize_array((array) $_REQUEST[‘combinations’]);159160 $possible_attributes = array();161 //for set_product_attributes162 $set_product_attributes = array();163164 //***165166 if (!empty($products_ids) AND!empty($combinations)) {167168 //lets prepare combinations for applying169 $terms = array();170 foreach ($combinations as $comb) {171 if (!empty($comb)) {172 foreach ($comb as $term_id) {173 $terms[$term_id] = get_term($term_id, '’, ARRAY_A);174 }175 }176 }177178 //***179180 foreach ($terms as $t) {181 $set_product_attributes[$t[‘taxonomy’]][] = $t[‘term_id’];182 }183184 foreach ($combinations as $k => $comb) {185 if (!empty($comb)) {186 foreach ($comb as $term_id) {187 $possible_attributes[$k][strtolower(urlencode($terms[$term_id][‘taxonomy’]))] = $terms[$term_id][‘slug’];188 }189 }190 }191192 //***193 //wp-content\plugins\woocommerce\includes\class-wc-ajax.php -> public static function link_all_variations194 wc_maybe_define_constant('WC_MAX_LINKED_VARIATIONS’, 50);195 wc_set_time_limit(0);196197198 /*199 * Leaved as an example of data structure200 $possible_attributes = array(201 ‘pa_color’ => array('black’, 'blue’, ‘green’),202 ‘pa_size’ => array('xl’, ‘2xxl’)203 );204205 $set_product_attributes = array(206 ‘pa_color’ => array(1, 2, 3),207 ‘pa_size’ => array(4, 5)208 );209 */210211212 if (!empty($possible_attributes)) {213214 foreach ($products_ids as $product_id) {215216 $product_id = intval($product_id);217 $product = $this->products->get_product($product_id);218219 //if product is not variable - no variations!!220 if (!$product->is_type(‘variable’)) {221 continue;222 }223224 //attach attributes if they not been attached225 foreach ($set_product_attributes as $field_key => $value) {226 $this->products->set_product_attributes($product_id, $field_key, $value, 'append’, array(‘set_variation’));227228 }229230 //***231 // Get existing variations so we don’t create duplicates.232 $existing_variations = array_map('wc_get_product’, $product->get_children());233 $parent_sku = $product->get_sku();234 $existing_attributes = array();235236 foreach ($existing_variations as $existing_variation) {237 if ($existing_variation) {238 $existing_attributes[] = $existing_variation->get_attributes();239 }240 }241242243 $regular_price = get_post_meta($product_id, '_regular_price’, true);244 $sale_price = get_post_meta($product_id, '_sale_price’, true);245 //***246247 foreach ($possible_attributes as $possible_attribute) {248249 if (in_array($possible_attribute, $existing_attributes)) {250 continue;251 }252253 $variation = new WC_Product_Variation();254 $variation->set_parent_id($product_id);255 $variation->set_attributes($possible_attribute);256 257 $variation->set_status(apply_filters('woobe_new_variation_product_status’, ‘publish’));258 259260 if ($regular_price) {261 $variation->set_regular_price($regular_price);262 }263 if ($sale_price) {264 $variation->set_sale_price($sale_price);265 }266267268 //do_action('product_variation_linked’, $variation->save());269 $variation->save();270271 //to avoid the same SKU as in the parent272 if (empty($parent_sku)) {273 $variation->set_sku('sku-' . $variation->get_id());274 } else {275 $variation->set_sku($parent_sku . '-' . $variation->get_id());276 }277 $variation->set_manage_stock(0);278 $variation->set_stock_quantity(0);279 $variation->save();280281 //clean_post_cache($variation->get_id());282 //wp_cache_flush();283 }284285286 //***287 //set order of variations288 $data_store = $product->get_data_store();289 $data_store->sort_all_product_variations($product->get_id());290 }291 }292 }293294 die(‘done’);295 }296297 //************ TAB 2298 //ajax299 public function woobe_bulkoperations_apply_default_combination() {300 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {301 die(‘0’);302 }303 if (!isset($_REQUEST[‘products_ids’])) {304 die(‘0’);305 }306307 //***308309 $products_ids = array_map(function($item) {310 return intval($item); //sanitize intval311 }, $_REQUEST[‘products_ids’]);312 313 $combination = WOOBE_HELPER::sanitize_array((array) $_REQUEST[‘combination’]);314315 if (!empty($combination) AND!empty($products_ids)) {316 foreach ($products_ids as $product_id) {317 $product = $this->products->get_product($product_id);318 $product->set_props(array(319 ‘default_attributes’ => $combination320 ));321 $product->save();322323 //*** also lets set order of attributes which customer will see on the product page324 $meta = get_post_meta($product_id, '_product_attributes’, true);325326 $new_meta = array();327 $counter = 0;328 foreach (array_keys($combination) as $meta_key) {329 if (isset($meta[$meta_key])) {330 $new_meta[$meta_key] = $meta[$meta_key];331 $new_meta[$meta_key][‘position’] = $counter;332 unset($meta[$meta_key]);333 $counter++;334 }335 }336337 //if we have more attributes than trying to save in order338 if (!empty($meta)) {339 foreach ($meta as $meta_key => $value) {340 $new_meta[$meta_key] = $value;341 $new_meta[$meta_key][‘position’] = $counter;342 $counter++;343 }344 }345346 update_post_meta($product_id, '_product_attributes’, $new_meta);347348 //woocommerce\includes\admin\meta-boxes\class-wc-meta-box-product-data.php349 //public static function save($post_id, $post)350 do_action(‘woocommerce_process_product_meta_’ . $product->get_type(), $product_id);351 }352 }353354 exit;355 }356357 //************ TAB 3358 //ajax359 public function woobe_bulkoperations_delete() {360 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {361 die(‘0’);362 }363 if (!isset($_REQUEST[‘products_ids’])) {364 die(‘0’);365 }366367 //***368369 $removed_ids = array();370 $products_ids = array_map(function($item) {371 return intval($item); //sanitize intval372 }, $_REQUEST[‘products_ids’]);373374 $combination = array();375 if (isset($_REQUEST[‘combination’])) {376 $combination = WOOBE_HELPER::sanitize_array((array) $_REQUEST[‘combination’]);377 }378379 if (!empty($products_ids)) {380 foreach ($products_ids as $product_id) {381 $product = $this->products->get_product($product_id);382383 if (method_exists($product, ‘is_type’) AND $product->is_type(‘variable’)) {384 $vars = $product->get_children();385386 if (!empty($vars)) {387 foreach ($vars as $var_id) {388389 $var = $this->products->get_product($var_id);390 $av = $product->get_available_variation($var);391392 if ($_REQUEST[‘delete_how’] == ‘combo’) {393394 if (!empty($combination)) {395 if (count($av[‘attributes’]) === count($combination)) {396 $is = FALSE;397 $attributes = array();398399 //fix for non-latin symbols400 if (!empty($av[‘attributes’])) {401 foreach ($av[‘attributes’] as $k => $v) {402 $attributes[urldecode($k)] = urldecode($v);403 }404 }405406407 foreach ($combination as $comb_key => $comb_value) {408 if (isset($attributes[‘attribute_’ . urldecode($comb_key)]) AND $attributes[‘attribute_’ . urldecode($comb_key)] == urldecode($comb_value)) {409 $is = TRUE;410 } else {411 $is = FALSE;412 break;413 }414 }415416 //removing417 if ($is) {418 $var_prod = $this->products->get_product($av[‘variation_id’]);419 $removed_ids[] = $av[‘variation_id’];420 $var_prod->delete(true);421 }422 }423 }424 } else {425 //all426 $var_prod = $this->products->get_product($av[‘variation_id’]);427 $removed_ids[] = $av[‘variation_id’];428 if ($var_prod){ 429 $var_prod->delete(true);430 }431 }432 }433 }434 }435436 //***437 }438 }439440 //***441 $removed_ids = json_encode($removed_ids);442 die($removed_ids);443 }444445 //************ TAB 4446 //ajax447 public function woobe_bulkoperations_get_product_variations() {448 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {449 die(‘0’);450 } 451 $product_id = intval($_REQUEST[‘product_id’]);452 $available_variations = array();453454 if ($product_id > 0) {455 try {456 $product = $this->products->get_product($product_id);457458 if (is_object($product) AND $product->is_type(‘variable’)) {459 $vars = $product->get_children();460461 if (!empty($vars)) {462 foreach ($vars as $var_id) {463 $var = $this->products->get_product($var_id);464 $av = $product->get_available_variation($var);465 $available_variations[$var_id][‘title’] = str_replace($product->get_title(), '’, $this->products->generate_product_title($var));466 $available_variations[$var_id][‘attributes’] = $av[‘attributes’];467 }468 }469470 //print_r($available_variations);471 }472 } catch (Exception $e) {473 //***474 }475 }476477 die(json_encode($available_variations));478 }479480 //ajax481 public function woobe_bulkoperations_ordering() {482 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {483 die(‘0’);484 }485 $products_ids = array_map(function($item) {486 return intval($item); //sanitize intval487 }, $_REQUEST[‘products_ids’]);488489 $combination = WOOBE_HELPER::sanitize_array((array) $_REQUEST[‘combination’]);490491 //***492493 if (!empty($products_ids) AND!empty($combination)) {494 foreach ($products_ids as $product_id) {495 $available_variations = array();496 $product = $this->products->get_product($product_id);497 $childrens = $product->get_children();498499 if (!empty($childrens)) {500 foreach ($childrens as $child_id) {501 $variation = $this->products->get_product($child_id);502 $available_variations[] = $product->get_available_variation($variation);503 }504505 //***506507 if (!empty($available_variations)) {508 foreach ($available_variations as $var) {509 $att = $var[‘attributes’];510 $num = -1;511 foreach ($combination as $n => $comb_var) {512 //lets look is it the same set of attributes as in $var513 $ak_att = array_keys($att);514 $ak_cv = array_keys($comb_var);515 sort($ak_att);516 sort($ak_cv);517 if ($ak_att === $ak_cv) {518 $av_att = array_values($att);519 $av_cv = array_values($comb_var);520 sort($av_att);521 sort($av_cv);522 if ($av_att === $av_cv) {523 $num = $n;524 break;525 }526 }527 }528529 //***530 if ($num > -1) {531 $this->products->update_page_field(intval($var[‘variation_id’]), 'menu_order’, $num);532 }533 }534 }535 }536 }537 }538539540 exit;541 }542543 //************ TAB 5 swap544 //ajax545 public function woobe_bulkoperations_swap() {546 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {547 die(‘0’);548 }549 $do = true;550 if (!empty($_REQUEST[‘from’]) AND!empty($_REQUEST[‘to’])) {551 if ($_REQUEST[‘from’][‘attribute’] == $_REQUEST[‘to’][‘attribute’]) {552 if ($_REQUEST[‘from’][‘term’] == $_REQUEST[‘to’][‘term’]) {553 $do = false;554 }555 }556 } else {557 $do = false;558 }559560 //***561562 if ($do) {563 $from_att = sanitize_text_field($_REQUEST[‘from’][‘attribute’]);564 $to_att = sanitize_text_field($_REQUEST[‘to’][‘attribute’]);565566 //***567568 if (!empty($_REQUEST[‘products_ids’])) {569 foreach ($_REQUEST[‘products_ids’] as $product_id) {570 $product_id = intval($product_id);571 $product = $this->products->get_product($product_id);572573 //***574575 if (!in_array($product->get_type(), array('variable’, ‘variation’))) {576 continue;577 }578579 //***580581 if ($product->is_type(‘variable’)) {582 $childrens = $product->get_children();583 $parent_id = $product_id;584 $parent_product = $product;585 } else {586 $childrens = array($product_id);587 $parent_id = $product->get_parent_id();588 $parent_product = $this->products->get_product($parent_id);589 }590591592 $parent_terms = wc_get_product_terms($parent_id, $to_att, array(‘fields’ => ‘slugs’));593594 if (!empty($childrens)) {595 foreach ($childrens as $child_id) {596 $variation = $this->products->get_product($child_id);597 $available_variations = $parent_product->get_available_variation($variation);598599 //***600601 if (isset($available_variations[‘attributes’]) AND!empty($available_variations[‘attributes’])) {602 if (isset($available_variations[‘attributes’][‘attribute_’ . $from_att])) {603 if ($available_variations[‘attributes’][‘attribute_’ . $from_att] === sanitize_text_field($_REQUEST[‘from’][‘term’])) {604605 $possible_attributes = $available_variations[‘attributes’];606607 if ($from_att !== $to_att) {608 unset($possible_attributes[‘attribute_’ . $from_att]);609 }610611 $possible_attributes[‘attribute_’ . $to_att] = sanitize_text_field($_REQUEST[‘to’][‘term’]);612613 //if such attribute not selected in the parent product Attributes tab lets attach it here614 if (!in_array($_REQUEST[‘to’][‘term’], $parent_terms)) {615 $p_terms = [];616 foreach($parent_terms as $t_slug){617 $t_term= get_term_by('slug’, sanitize_text_field($t_slug), $to_att);618 if($t_term){619 $p_terms[] = $t_term->term_id;620 }621 622 }623 $t = get_term_by('slug’, sanitize_text_field($_REQUEST[‘to’][‘term’]), $to_att);624 $p_terms[] = $t->term_id;625626 $this->products->update_page_field($parent_id, $to_att, $p_terms);627 }628629 $variation->set_attributes($possible_attributes);630 $variation->save();631 }632 }633 }634 }635 }636 }637 }638 }639640 die(‘done’);641 }642643 //************ TAB 6 attaching644 //ajax645 public function woobe_bulkoperations_attaching() {646 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {647 die(‘0’);648 }649 $selected_attribute = sanitize_text_field($_REQUEST[‘selected_attribute’]);650 $attaching_att = $_REQUEST[‘attaching_att’]; //sanitizing in cycle651 $products_ids = $_REQUEST[‘products_ids’]; //sanitizing in cycle652 //***653654 if (!empty($products_ids)) {655 if (!empty($selected_attribute) AND $attaching_att) {656 foreach ($products_ids as $product_id) {657 $product_id = intval($product_id); //sanitizing658659 $product = $this->products->get_product($product_id);660661 if ($product->is_type(‘variable’)) {662 $childrens = $product->get_children();663664 //***665 if (!empty($childrens)) {666 foreach ($childrens as $child_id) {667 $variation = $this->products->get_product($child_id);668 $available_variations = $product->get_available_variation($variation);669670 //***671672 if (isset($available_variations[‘attributes’]) AND!empty($available_variations[‘attributes’])) {673674 //if its empty - will be filled up, if not empty will be replaced if not selected 'ignore’675 $possible_attributes = $available_variations[‘attributes’];676677 //***678679 foreach ($attaching_att as $set) {680681 if (isset($possible_attributes[‘attribute_’ . $selected_attribute])) {682 unset($possible_attributes[‘attribute_’ . $selected_attribute]);683 }684685 if (isset($set[‘attributes’][‘attribute_’ . $selected_attribute])) {686 unset($set[‘attributes’][‘attribute_’ . $selected_attribute]);687 }688689 //***690691 $att_set_now_keys = array_keys($possible_attributes);692 $set_keys = array_keys($set[‘attributes’]);693 sort($att_set_now_keys);694 sort($set_keys);695696 if ($att_set_now_keys === $set_keys) {697 $att_set_now_vals = array_values($possible_attributes);698 $set_vals = array_values($set[‘attributes’]);699 sort($att_set_now_vals);700 sort($set_vals);701 if ($att_set_now_vals === $set_vals AND $set[‘value’] !== ‘woobe-ignore’) {702 $possible_attributes[‘attribute_’ . $selected_attribute] = sanitize_text_field($set[‘value’]);703704 //if such attribute not selected in the parent product Attributes tab lets attach it here705 $parent_terms = wc_get_product_terms($product_id, $selected_attribute, array(‘fields’ => ‘ids’));706 if (!in_array($set[‘value’], $parent_terms)) {707 $t = get_term_by('slug’, sanitize_text_field($set[‘value’]), $selected_attribute);708 $parent_terms[] = $t->term_id;709 $this->products->update_page_field($product_id, $selected_attribute, $parent_terms, '’, array(‘set_variation’));710711 }712713714 $variation->set_attributes($possible_attributes);715 $variation->save();716 break;717 }718 }719 }720 }721 }722 }723 724 //fix visibility725 $meta = get_post_meta($product_id, '_product_attributes’, true);726 if (is_array($meta)) {727 foreach ($meta as $pa_key => $item) {728 if ($item[‘name’] == ‘pa_size’) {729 $meta[$pa_key][‘is_visible’] = 1;730 $meta[$pa_key][‘is_variation’] = 1;731 }732 }733 }734 update_post_meta($product_id, '_product_attributes’, $meta); 735 }736 }737 }738 }739740 //***741742 die(‘done’);743 }744745 //************ TAB 7 visibility746 //ajax747 public function woobe_bulkoperations_visibility() {748 if (!isset($_REQUEST[‘bulkoperations_nonce’]) || !wp_verify_nonce($_REQUEST[‘bulkoperations_nonce’], ‘woobe_bulkoperations_nonce’)) {749 die(‘0’);750 }751 if (isset($_REQUEST[‘products_ids’])) {752 $products_ids = $_REQUEST[‘products_ids’]; //sanitizing in cycle753 $vis_data = $_REQUEST[‘vis_data’]; //sanitizing in cycle754755 if (!empty($products_ids) AND!empty($vis_data)) {756 foreach ($products_ids as $product_id) {757 $product_id = intval($product_id);758759 $product = $this->products->get_product($product_id);760 if ($product->is_type(‘variable’)) {761 $meta = get_post_meta($product_id, '_product_attributes’, true);762763764 foreach ($vis_data as $vis) {765 if (is_array($meta)) {766 foreach ($meta as $pa_key => $item) {767 if ($item[‘name’] == $vis[‘attribute’]) {768 $meta[$pa_key][‘is_visible’] = intval($vis[‘is_visible’]);769 $meta[$pa_key][‘is_variation’] = intval($vis[‘is_variation’]);770 }771 }772 }773 }774 update_post_meta($product_id, '_product_attributes’, $meta);775 }776 }777 }778 }779780 die(‘done’);781 }782783}