/**
  * Convert a WC Product or Variation into a Square ItemVariation
  * See: https://docs.connect.squareup.com/api/connect/v1/#datatype-itemvariation
  *
  * @param WC_Product|WC_Product_Variation $variation
  * @param bool                            $include_inventory
  * @return array Formatted as a Square ItemVariation
  */
 public static function format_wc_variation_for_square_api($variation, $include_inventory = false)
 {
     $formatted = array('name' => null, 'pricing_type' => null, 'price_money' => null, 'sku' => null, 'track_inventory' => null, 'inventory_alert_type' => null, 'inventory_alert_threshold' => null, 'user_data' => null);
     if ($variation instanceof WC_Product) {
         $formatted['name'] = __('Regular', 'woocommerce-square');
         $formatted['price_money'] = array('currency_code' => apply_filters('woocommerce_square_currency', get_woocommerce_currency()), 'amount' => $variation->get_display_price() * 100);
         $formatted['sku'] = $variation->get_sku();
         if ($include_inventory && $variation->managing_stock()) {
             $formatted['track_inventory'] = true;
         }
     }
     if ($variation instanceof WC_Product_Variation) {
         $formatted['name'] = implode(', ', $variation->get_variation_attributes());
     }
     return array_filter($formatted);
 }
 /**
  * Get the attributes for a product or product variation
  *
  * @since 2.1
  * @param WC_Product|WC_Product_Variation $product
  * @return array
  */
 private function get_attributes($product)
 {
     $attributes = array();
     if ($product->is_type('variation')) {
         // variation attributes
         foreach ($product->get_variation_attributes() as $attribute_name => $attribute) {
             // taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`
             $attributes[] = array('name' => wc_attribute_label(str_replace('attribute_', '', $attribute_name)), 'slug' => str_replace('attribute_', '', str_replace('pa_', '', $attribute_name)), 'option' => $attribute);
         }
     } else {
         foreach ($product->get_attributes() as $attribute) {
             // taxonomy-based attributes are comma-separated, others are pipe (|) separated
             if ($attribute['is_taxonomy']) {
                 $options = explode(',', $product->get_attribute($attribute['name']));
             } else {
                 $options = explode('|', $product->get_attribute($attribute['name']));
             }
             $attributes[] = array('name' => wc_attribute_label($attribute['name']), 'slug' => str_replace('pa_', '', $attribute['name']), 'position' => (int) $attribute['position'], 'visible' => (bool) $attribute['is_visible'], 'variation' => (bool) $attribute['is_variation'], 'options' => array_map('trim', $options));
         }
     }
     return $attributes;
 }
 /**
  * Add a product line item to the order. This is the only line item type with
  * it's own method because it saves looking up order amounts (costs are added up for you).
  * @param  \WC_Product $product
  * @param  int $qty
  * @param  array $args
  * @return int order item ID
  * @throws WC_Data_Exception
  */
 public function add_product($product, $qty = 1, $args = array())
 {
     if ($product) {
         $default_args = array('name' => $product->get_title(), 'tax_class' => $product->get_tax_class(), 'product_id' => $product->get_id(), 'variation_id' => isset($product->variation_id) ? $product->variation_id : 0, 'variation' => isset($product->variation_id) ? $product->get_variation_attributes() : array(), 'subtotal' => $product->get_price_excluding_tax($qty), 'total' => $product->get_price_excluding_tax($qty), 'quantity' => $qty);
     } else {
         $default_args = array('quantity' => $qty);
     }
     $args = wp_parse_args($args, $default_args);
     // BW compatibility with old args
     if (isset($args['totals'])) {
         foreach ($args['totals'] as $key => $value) {
             if ('tax' === $key) {
                 $args['total_tax'] = $value;
             } elseif ('tax_data' === $key) {
                 $args['taxes'] = $value;
             } else {
                 $args[$key] = $value;
             }
         }
     }
     $item = new WC_Order_Item_Product($args);
     $item->set_backorder_meta();
     $item->set_order_id($this->get_id());
     $item->save();
     $this->add_item($item);
     wc_do_deprecated_action('woocommerce_order_add_product', array($this->get_id(), $item->get_id(), $product, $qty, $args), '2.7', 'Use woocommerce_new_order_item action instead.');
     return $item->get_id();
 }
    public function render_product_tab_content()
    {
        global $woocommerce, $post;
        global $_wp_additional_image_sizes;
        add_filter('woocommerce_variation_is_visible', array($this, 'return_true'));
        $post_id = $post->ID;
        if (function_exists('get_product')) {
            $product = get_product($post->ID);
        } else {
            $product = new WC_Product($post->ID);
        }
        $product_type_array = array('variable', 'variable-subscription');
        if (!in_array($product->product_type, $product_type_array)) {
            return;
        }
        $swatch_type_options = get_post_meta($post_id, '_swatch_type_options', true);
        $swatch_type = get_post_meta($post_id, '_swatch_type', true);
        $swatch_size = get_post_meta($post_id, '_swatch_size', true);
        if (!$swatch_type_options) {
            $swatch_type_options = array();
        }
        if (!$swatch_type) {
            $swatch_type = 'standard';
        }
        if (!$swatch_size) {
            $swatch_size = 'swatches_image_size';
        }
        echo '<div class="options_group">';
        ?>

		<div class="fields_header">
			<table class="wcsap widefat">
				<thead>
				<th class="attribute_swatch_label">
					<?php 
        _e('Product Attribute Name', 'wc_swatches_and_photos');
        ?>
				</th>
				<th class="attribute_swatch_type">
					<?php 
        _e('Attribute Control Type', 'wc_swatches_and_photos');
        ?>
				</th>
				</thead>
			</table>
		</div>
		<div class="fields">

			<?php 
        $woocommerce_taxonomies = WC_Swatches_Compatibility::wc_get_attribute_taxonomies();
        $woocommerce_taxonomy_infos = array();
        foreach ($woocommerce_taxonomies as $tax) {
            $woocommerce_taxonomy_infos[WC_Swatches_Compatibility::wc_attribute_taxonomy_name($tax->attribute_name)] = $tax;
        }
        $tax = null;
        $attributes = $product->get_variation_attributes();
        //Attributes configured on this product already.
        if ($attributes && count($attributes)) {
            $attribute_names = array_keys($attributes);
            foreach ($attribute_names as $name) {
                $key = md5(sanitize_title($name));
                $old_key = sanitize_title($name);
                $key_attr = md5(str_replace('-', '_', sanitize_title($name)));
                $current_is_taxonomy = taxonomy_exists($name);
                $current_type = 'default';
                $current_type_description = 'None';
                $current_size = 'swatches_image_size';
                $current_layout = 'default';
                $current_size_height = '32';
                $current_size_width = '32';
                $current_label = 'Unknown';
                $current_options = false;
                if (isset($swatch_type_options[$key])) {
                    $current_options = $swatch_type_options[$key];
                } elseif (isset($swatch_type_options[$old_key])) {
                    $current_options = $swatch_type_options[$old_key];
                }
                if ($current_options) {
                    $current_size = $current_options['size'];
                    $current_type = $current_options['type'];
                    $current_layout = isset($current_options['layout']) ? $current_options['layout'] : 'default';
                    if ($current_type != 'default') {
                        $current_type_description = $current_type == 'term_options' ? __('Taxonomy Colors and Images', 'wc_swatches_and_photos') : __('Custom Product Colors and Images', 'wc_swatches_and_photos');
                    }
                }
                $the_size = isset($_wp_additional_image_sizes[$current_size]) ? $_wp_additional_image_sizes[$current_size] : $_wp_additional_image_sizes['swatches_image_size'];
                if (isset($the_size['width']) && isset($the_size['height'])) {
                    $current_size_width = $the_size['width'];
                    $current_size_height = $the_size['height'];
                } else {
                    $current_size_width = 32;
                    $current_size_height = 32;
                }
                $attribute_terms = array();
                if (taxonomy_exists($name)) {
                    $tax = get_taxonomy($name);
                    $woocommerce_taxonomy = $woocommerce_taxonomy_infos[$name];
                    $current_label = isset($woocommerce_taxonomy->attribute_label) && !empty($woocommerce_taxonomy->attribute_label) ? $woocommerce_taxonomy->attribute_label : $woocommerce_taxonomy->attribute_name;
                    $terms = get_terms($name, array('hide_empty' => false));
                    $selected_terms = isset($attributes[$name]) ? $attributes[$name] : array();
                    foreach ($terms as $term) {
                        if (in_array($term->slug, $selected_terms)) {
                            $attribute_terms[] = array('id' => md5($term->slug), 'label' => $term->name, 'old_id' => $term->slug);
                        }
                    }
                } else {
                    $current_label = esc_html($name);
                    foreach ($attributes[$name] as $term) {
                        $attribute_terms[] = array('id' => md5(sanitize_title(strtolower($term))), 'label' => esc_html($term), 'old_id' => esc_attr(sanitize_title($term)));
                    }
                }
                ?>
					<div class="field">
						<div class="wcsap_field_meta">
							<table class="wcsap widefat">
								<tbody>
									<tr>
										<td class="attribute_swatch_label">
											<strong><a class="wcsap_edit_field row-title" href="javascript:;"><?php 
                echo $current_label;
                ?>
</a></strong>
										</td>
										<td class="attribute_swatch_type">
											<?php 
                echo $current_type_description;
                ?>
										</td>
									</tr>
								</tbody>
							</table>
						</div>
						<div class="field_form_mask">
							<div class="field_form">
								<table class="wcsap_input widefat wcsap_field_form_table">
									<tbody>
										<tr class="attribute_swatch_type">
											<td class="label">
												<label for="_swatch_type_options_<?php 
                echo $key_attr;
                ?>
_type">Type</label>
											</td>
											<td>
												<select class="_swatch_type_options_type" id="_swatch_type_options_<?php 
                echo $key_attr;
                ?>
_type" name="_swatch_type_options[<?php 
                echo $key;
                ?>
][type]">
													<option <?php 
                selected($current_type, 'default');
                ?>
 value="default">None</option>
													<?php 
                if ($current_is_taxonomy) {
                    ?>
														<option <?php 
                    selected($current_type, 'term_options');
                    ?>
 value="term_options"><?php 
                    _e('Taxonomy Colors and Images', 'wc_swatches_and_photos');
                    ?>
</option>
													<?php 
                }
                ?>
													<option <?php 
                selected($current_type, 'product_custom');
                ?>
 value="product_custom"><?php 
                _e('Custom Colors and Images', 'wc_swatches_and_photos');
                ?>
</option>
												</select>
											</td>
										</tr>

										<tr class="field_option field_option_product_custom field_option_term_options" style="<?php 
                echo $current_type != 'product_custom' && $current_type != 'term_options' ? 'display:none;' : '';
                ?>
">
											<td class="label">
												<label for="_swatch_type_options_<?php 
                echo $key_attr;
                ?>
_layout">Layout</label>
											</td>
											<td>
												<?php 
                $layouts = array('default' => __('No Label', 'wc_swatches_and_photos'), 'label_above' => __('Show label above', 'wc_swatches_and_photos'));
                ?>
												<select name="_swatch_type_options[<?php 
                echo $key;
                ?>
][layout]">
													<?php 
                foreach ($layouts as $layout => $layout_name) {
                    ?>
														<option <?php 
                    selected($current_layout, $layout);
                    ?>
 value="<?php 
                    echo $layout;
                    ?>
"><?php 
                    echo $layout_name;
                    ?>
</option>
													<?php 
                }
                ?>
												</select>
											</td>
										</tr>

										<tr class="field_option field_option_product_custom" style="<?php 
                echo $current_type != 'product_custom' ? 'display:none;' : '';
                ?>
">
											<td class="label">
												<label for="_swatch_type_options_<?php 
                echo $key_attr;
                ?>
_size">Size</label>
											</td>
											<td>
												<?php 
                $image_sizes = get_intermediate_image_sizes();
                ?>
												<select id="_swatch_type_options_pa_color_size" name="_swatch_type_options[<?php 
                echo $key;
                ?>
][size]">
													<?php 
                foreach ($image_sizes as $size) {
                    ?>
														<option <?php 
                    selected($current_size, $size);
                    ?>
 value="<?php 
                    echo $size;
                    ?>
"><?php 
                    echo $size;
                    ?>
</option>
													<?php 
                }
                ?>
												</select>
											</td>
										</tr>

										<tr class="field_option field_option_term_default" style="<?php 
                echo $current_type != 'default' ? 'display:none;' : '';
                ?>
">
											<td class="label">

											</td>
											<td>
												<p>
													<?php 
                _e('WooCommerce default select boxes will be used for this product attribute', 'wc_swatches_and_photos');
                ?>
												</p>
											</td>
										</tr>

										<tr class="field_option field_option_term_options" style="<?php 
                echo $current_type != 'term_options' ? 'display:none;' : '';
                ?>
">
											<td class="label">

											</td>
											<td>
												<p>
													<?php 
                printf(__('The color swatch and image configuration will be used from the %s taxonomy.  Navigate to Products -> Attributes to edit the shared swatches and images for this product attribute.', 'wc_swatches_and_photos'), $current_label);
                ?>
												</p>
											</td>
										</tr>

										<tr class="field_option field_option_product_custom" style="<?php 
                echo $current_type != 'product_custom' ? 'display:none;' : '';
                ?>
">

											<td class="label">
												<label>Attribute Configuration</label>
											</td>
											<td>
												<div class="product_custom">

													<div class="fields_header">
														<table class="wcsap widefat">
															<thead>
															<th class="attribute_swatch_preview">
																<?php 
                _e('Preview', 'wc_swatches_and_photos');
                ?>
															</th>
															<th class="attribute_swatch_label">
																<?php 
                _e('Attribute', 'wc_swatches_and_photos');
                ?>
															</th>
															<th class="attribute_swatch_type">
																<?php 
                _e('Type', 'wc_swatches_and_photos');
                ?>
															</th>
															</thead>
														</table>
													</div>

													<div class="fields">
														<?php 
                foreach ($attribute_terms as $attribute_term) {
                    ?>
															<?php 
                    $attribute_term['id'] = $attribute_term['id'];
                    $current_attribute_type = 'color';
                    $current_attribute_color = '#FFFFFF';
                    $current_attribute_image_src = WC_Swatches_Compatibility::wc_placeholder_img_src();
                    $current_attribute_image_id = 0;
                    $current_attribute_options = false;
                    if (isset($current_options['attributes'][$attribute_term['id']])) {
                        $current_attribute_options = isset($current_options['attributes'][$attribute_term['id']]) ? $current_options['attributes'][$attribute_term['id']] : false;
                    } elseif (isset($current_options['attributes'][$attribute_term['old_id']])) {
                        $current_attribute_options = isset($current_options['attributes'][$attribute_term['old_id']]) ? $current_options['attributes'][$attribute_term['old_id']] : false;
                    }
                    if ($current_attribute_options) {
                        $current_attribute_type = $current_attribute_options['type'];
                        $current_attribute_color = $current_attribute_options['color'];
                        $current_attribute_image_id = $current_attribute_options['image'];
                        if ($current_attribute_image_id) {
                            $current_attribute_image_src = wp_get_attachment_image_src($current_attribute_image_id, $current_size);
                            $current_attribute_image_src = $current_attribute_image_src[0];
                        }
                    } elseif ($current_is_taxonomy) {
                    }
                    ?>

															<div class="sub_field field">

																<div class="wcsap_field_meta">

																	<table class="wcsap widefat">

																		<tbody>
																		<td class="attribute_swatch_preview">
																			<div class="select-option swatch-wrapper">
																				<a id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_color_preview_image" href="javascript:;"
																				   class="image"
																				   style="width:16px;height:16px;<?php 
                    echo $current_attribute_type == 'image' ? '' : 'display:none;';
                    ?>
">
																					<img src="<?php 
                    echo $current_attribute_image_src;
                    ?>
" class="wp-post-image" width="16px" height="16px" />
																				</a>
																				<a id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_color_preview_swatch" href="javascript:;"
																				   class="swatch"
																				   style="text-indent:-9999px;width:16px;height:16px;background-color:<?php 
                    echo $current_attribute_color;
                    ?>
;<?php 
                    echo $current_attribute_type == 'color' ? '' : 'display:none;';
                    ?>
"><?php 
                    echo $attribute_term['label'];
                    ?>
																				</a>
																			</div>
																		</td>
																		<td class="attribute_swatch_label">
																			<strong><a class="wcsap_edit_field row-title" href="javascript:;"><?php 
                    echo $attribute_term['label'];
                    ?>
</a></strong>
																		</td>
																		<td class="attribute_swatch_type">
																			<?php 
                    _e('Color Swatch', 'wc_swatches_and_photos');
                    ?>
																		</td>
																		<tbody>

																	</table>

																</div>

																<div class="field_form_mask">
																	<div class="field_form">
																		<table class="wcsap_input widefat">
																			<tbody>
																				<tr class="attribute_swatch_type">
																					<td class="label">
																						<label for="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo esc_attr($attribute_term['id']);
                    ?>
">
																							<?php 
                    _e('Attribute Color or Image', 'wc_swatches_and_photos');
                    ?>
																						</label>
																					</td>
																					<td>
																						<select class="_swatch_type_options_attribute_type" id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo esc_attr($attribute_term['id']);
                    ?>
_type" name="_swatch_type_options[<?php 
                    echo $key;
                    ?>
][attributes][<?php 
                    echo esc_attr($attribute_term['id']);
                    ?>
][type]">
																							<option <?php 
                    selected($current_attribute_type, 'color');
                    ?>
 value="color">Color</option>
																							<option <?php 
                    selected($current_attribute_type, 'image');
                    ?>
 value="image">Image</option>
																						</select>
																					</td>
																				</tr>

																				<tr class="field_option field_option_color" style="<?php 
                    echo $current_attribute_type == 'color' ? '' : 'display:none;';
                    ?>
">
																					<td class="label">
																						<label><?php 
                    _e('Color', 'wc_swatches_and_photos');
                    ?>
</label>
																					</td>
																					<td class="section-color-swatch">
																						<div id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_color_picker" class="colorSelector"><div></div></div>
																						<input class="woo-color" id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_color" type="text" class="text" name="_swatch_type_options[<?php 
                    echo $key;
                    ?>
][attributes][<?php 
                    echo esc_attr($attribute_term['id']);
                    ?>
][color]" value="<?php 
                    echo $current_attribute_color;
                    ?>
" />
																					</td>
																				</tr>

																				<tr class="field_option field_option_image" style="<?php 
                    echo $current_attribute_type == 'image' ? '' : 'display:none;';
                    ?>
">
																					<td class="label">
																						<label><?php 
                    _e('Image', 'wc_swatches_and_photos');
                    ?>
</label>
																					</td>
																					<td>

																						<div style="line-height:60px;">
																							<div id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_image_thumbnail" style="float:left;margin-right:10px;">
																								<img src="<?php 
                    echo $current_attribute_image_src;
                    ?>
" alt="<?php 
                    _e('Thumbnail Preview', 'wc_swatches_and_photos');
                    ?>
" class="wp-post-image swatch-photopa_colour_swatches_id" width="<?php 
                    echo '16px';
                    ?>
" height="<?php 
                    echo '16px';
                    ?>
">
																							</div>
																							<input class="upload_image_id" type="hidden" id="_swatch_type_options_<?php 
                    echo $key_attr;
                    ?>
_<?php 
                    echo $attribute_term['id'];
                    ?>
_image" name="_swatch_type_options[<?php 
                    echo $key;
                    ?>
][attributes][<?php 
                    echo esc_attr($attribute_term['id']);
                    ?>
][image]" value="<?php 
                    echo $current_attribute_image_id;
                    ?>
" />
																							<button type="submit" class="upload_image_button button" rel="<?php 
                    echo $post_id;
                    ?>
"><?php 
                    _e('Upload/Add image', 'woocommerce');
                    ?>
</button>
																							<button type="submit" class="remove_image_button button" rel="<?php 
                    echo $post_id;
                    ?>
"><?php 
                    _e('Remove image', 'woocommerce');
                    ?>
</button>
																						</div>

																					</td>
																				</tr>
																			</tbody>
																		</table>
																	</div>
																</div>

															</div>
														<?php 
                }
                ?>
													</div>

												</div>
											</td>
										</tr>
									</tbody>
								</table>
							</div>
						</div>
					</div>
					<?php 
            }
        } else {
            echo '<p>' . __('Add a at least one attribute / variation combination to this product that has been configured with color swatches or photos. After you add the attributes from the "Attributes" tab and create a variation, save the product and you will see the option to configure the swatch or photo picker here.', 'wc_swatches_and_photos') . '</p>';
        }
        ?>


		</div>

		<?php 
        echo '</div>';
        $this->do_javascript();
        parent::render_product_tab_content();
        remove_filter('woocommerce_variation_is_visible', array($this, 'return_true'));
    }
 /**
  * Get the attributes for a product or product variation
  *
  * @since 2.1
  * @param WC_Product|WC_Product_Variation $product
  * @return array
  */
 private function get_attributes($product)
 {
     $attributes = array();
     if ($product->is_type('variation')) {
         // variation attributes
         foreach ($product->get_variation_attributes() as $attribute_name => $attribute) {
             // taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`
             $attributes[] = array('name' => ucwords(str_replace('attribute_', '', str_replace('pa_', '', $attribute_name))), 'option' => $attribute);
         }
     } else {
         foreach ($product->get_attributes() as $attribute) {
             $attributes[] = array('name' => ucwords(str_replace('pa_', '', $attribute['name'])), 'position' => $attribute['position'], 'visible' => (bool) $attribute['is_visible'], 'variation' => (bool) $attribute['is_variation'], 'options' => $this->get_attribute_options($product->get_id(), $attribute));
         }
     }
     return $attributes;
 }
 /**
  * Save default attributes.
  *
  * @since 2.7.0
  *
  * @param WC_Product      $product Product instance.
  * @param WP_REST_Request $request Request data.
  * @return WC_Product
  */
 protected function save_default_attributes($product, $request)
 {
     if (isset($request['default_attributes']) && is_array($request['default_attributes'])) {
         $attributes = $product->get_variation_attributes();
         $default_attributes = array();
         foreach ($request['default_attributes'] as $attribute) {
             $attribute_id = 0;
             $attribute_name = '';
             // Check ID for global attributes or name for product attributes.
             if (!empty($attribute['id'])) {
                 $attribute_id = absint($attribute['id']);
                 $attribute_name = wc_attribute_taxonomy_name_by_id($attribute_id);
             } elseif (!empty($attribute['name'])) {
                 $attribute_name = sanitize_title($attribute['name']);
             }
             if (!$attribute_id && !$attribute_name) {
                 continue;
             }
             if (isset($attributes[$attribute_name])) {
                 $_attribute = $attributes[$attribute_name];
                 if ($_attribute['is_variation']) {
                     $value = isset($attribute['option']) ? wc_clean(stripslashes($attribute['option'])) : '';
                     if (!empty($_attribute['is_taxonomy'])) {
                         // If dealing with a taxonomy, we need to get the slug from the name posted to the API.
                         $term = get_term_by('name', $value, $attribute_name);
                         if ($term && !is_wp_error($term)) {
                             $value = $term->slug;
                         } else {
                             $value = sanitize_title($value);
                         }
                     }
                     if ($value) {
                         $default_attributes[$attribute_name] = $value;
                     }
                 }
             }
         }
         $product->set_default_attributes($default_attributes);
     }
     return $product;
 }
 /**
  * Get the attributes for a product or product variation.
  *
  * @param WC_Product|WC_Product_Variation $product
  * @return array
  */
 protected function get_attributes($product)
 {
     $attributes = array();
     if ($product->is_type('variation')) {
         // Variation attributes.
         foreach ($product->get_variation_attributes() as $attribute_name => $attribute) {
             $name = str_replace('attribute_', '', $attribute_name);
             // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`.
             if (0 === strpos($attribute_name, 'attribute_pa_')) {
                 $attributes[] = array('id' => wc_attribute_taxonomy_id_by_name($name), 'name' => $this->get_attribute_taxonomy_label($name), 'option' => $attribute);
             } else {
                 $attributes[] = array('id' => 0, 'name' => str_replace('pa_', '', $name), 'option' => $attribute);
             }
         }
     } else {
         foreach ($product->get_attributes() as $attribute) {
             if ($attribute['is_taxonomy']) {
                 $attributes[] = array('id' => wc_attribute_taxonomy_id_by_name($attribute['name']), 'name' => $this->get_attribute_taxonomy_label($attribute['name']), 'position' => (int) $attribute['position'], 'visible' => (bool) $attribute['is_visible'], 'variation' => (bool) $attribute['is_variation'], 'options' => $this->get_attribute_options($product->id, $attribute));
             } else {
                 $attributes[] = array('id' => 0, 'name' => str_replace('pa_', '', $attribute['name']), 'position' => (int) $attribute['position'], 'visible' => (bool) $attribute['is_visible'], 'variation' => (bool) $attribute['is_variation'], 'options' => $this->get_attribute_options($product->id, $attribute));
             }
         }
     }
     return $attributes;
 }
        /**
         * Write panel for Product Bundles
         **/
        function woo_bundles_product_write_panel()
        {
            global $woocommerce, $post, $wpdb;
            ?>
				<div id="bundled_product_data" class="panel woocommerce_options_panel">

					<div class="options_group">

						<p><label for="bundled_ids"><?php 
            _e('Bundled Products', 'woo-bundles');
            ?>
</label>
						</p>

						<div class="wc-bundled_products">

							<div class="bundled_products_info">

							<?php 
            _e('Note', 'woo-bundles');
            echo '<img class="help_tip" data-tip="' . __('Select the products that you want to include in your bundle, kit, or assembly. Any simple or variable product can be added - physical, or downloadable.<br/><strong>Important</strong>: v2.0 has introduced the ability to bundle <strong>multiple instances of the same variable product</strong> and configure each instance separately - for details, check out the online documentation.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />';
            ?>

							</div>

							<div class="bundled_products_selector">

								<select id="bundled_ids" name="bundled_ids[]" class="ajax_chosen_select_products" multiple="multiple" data-placeholder="<?php 
            _e('Search for a product&hellip;', 'woo-bundles');
            ?>
">
									<?php 
            $item_ids = get_post_meta($post->ID, '_bundled_ids', true);
            $bundled_variable_num = 0;
            if ($item_ids) {
                foreach ($item_ids as $item_id) {
                    // remove suffix
                    $sep = explode('_', $item_id);
                    $product_id = $sep[0];
                    if ($terms = wp_get_object_terms($product_id, 'product_type')) {
                        $product_type = current($terms)->slug;
                    }
                    if ($product_type == 'variable') {
                        $bundled_variable_num++;
                    }
                    $title = get_the_title($product_id) . ($product_id != $item_id ? ' #' . $sep[1] : '');
                    $sku = get_post_meta($product_id, '_sku', true);
                    if (!$title) {
                        continue;
                    }
                    if (isset($sku) && $sku) {
                        $sku = ' (SKU: ' . $sku . ')';
                    }
                    echo '<option value="' . $product_id . '" selected="selected">' . $title . $sku . '</option>';
                }
            }
            ?>
								</select>
							</div>
						</div>

						<?php 
            if ($item_ids) {
                ?>

							<p><label for="bundled_ids_notice"><?php 
                _e('Bundle Configuration', 'woo-bundles');
                ?>
</label></p> <?php 
                $allowed_variations = get_post_meta($post->ID, '_allowed_variations', true);
                $default_attributes = (array) maybe_unserialize(get_post_meta($post->ID, '_bundle_defaults', true));
                foreach ($item_ids as $item_id) {
                    // remove suffix
                    $sep = explode('_', $item_id);
                    $product_id = $sep[0];
                    $title = get_the_title($product_id) . ($product_id != $item_id ? ' #' . $sep[1] : '');
                    $sku = get_post_meta($product_id, '_sku', true);
                    if (isset($sku) && $sku) {
                        $sku = ' (SKU: ' . $sku . ')';
                    }
                    if (!$title) {
                        continue;
                    }
                    ?>

								<div class="wc-bundled-item">
									<div class="item-description">
										<?php 
                    echo $title . ' &ndash; #' . $product_id;
                    ?>
<br/><?php 
                    echo $sku;
                    ?>
									</div>
									<div class="item-data">

										<?php 
                    if ($this->is_wc_v2()) {
                        $bundled_product = get_product($product_id);
                    } else {
                        $bundled_product = new WC_Product($product_id);
                    }
                    if ($bundled_product->is_type('variable')) {
                        ?>

												<div class="filtering">

												<?php 
                        woocommerce_wp_checkbox(array('id' => 'filter_variations_' . $item_id, 'wrapper_class' => 'filter_variations', 'label' => __('Filter Variations', 'woo-bundles'), 'description' => '<img class="help_tip" data-tip="' . __('Check to enable only a subset of the available variations.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />'));
                        ?>

												</div>


												<div class="bundle_variation_filters indented">

													<select multiple="multiple" name="allowed_variations[<?php 
                        echo $item_id;
                        ?>
][]" style="width: 450px; display: none; " data-placeholder="Choose variations…" title="Variations" class="chosen_select" > <?php 
                        $args = array('post_type' => 'product_variation', 'post_status' => array('private', 'publish'), 'numberposts' => -1, 'orderby' => 'menu_order', 'order' => 'asc', 'post_parent' => $product_id, 'fields' => 'ids');
                        $variations = get_posts($args);
                        foreach ($variations as $variation) {
                            $product_custom_fields = get_post_custom($variation);
                            ksort($product_custom_fields);
                            $description = '';
                            foreach ($product_custom_fields as $name => $value) {
                                if (!strstr($name, 'attribute_')) {
                                    continue;
                                }
                                $attribute_name = substr($name, strlen('attribute_'));
                                $description_name = ucwords($woocommerce->attribute_label($attribute_name));
                                if (!$value[0]) {
                                    $description_value = __('Any', 'woocommerce') . ' ' . $description_name;
                                } else {
                                    $term = get_term_by('slug', $value[0], $attribute_name);
                                    $description_value = $term == false ? '' : $term->name;
                                }
                                if (!$description_value) {
                                    $description_value = $value[0];
                                }
                                $description .= $description_name . ': ' . apply_filters('woocommerce_variation_option_name', $description_value) . ', ';
                            }
                            if (is_array($allowed_variations[$item_id]) && in_array($variation, $allowed_variations[$item_id])) {
                                $selected = 'selected="selected"';
                            } else {
                                $selected = '';
                            }
                            echo '<option value="' . $variation . '" ' . $selected . '>#' . $variation . ' - ' . rtrim($description, ', ') . '</option>';
                        }
                        ?>

													</select>

													<?php 
                        woocommerce_wp_checkbox(array('id' => 'hide_filtered_variations_' . $item_id, 'wrapper_class' => 'hide_filtered_variations', 'label' => __('Hide Filtered-Out Options', 'woo-bundles'), 'description' => '<img class="help_tip" data-tip="' . __('Check to remove any filtered-out variation options from this item\'s drop-downs. If you leave the box unchecked, the options corresponding to filtered-out variations will be disabled but still visible.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />'));
                        ?>

												</div>


												<div class="defaults">

													<?php 
                        woocommerce_wp_checkbox(array('id' => 'override_defaults_' . $item_id, 'wrapper_class' => 'override_defaults', 'label' => __('Override Default Selections', 'woo-bundles'), 'description' => '<img class="help_tip" data-tip="' . __('In effect for this bundle only. The available options are in sync with the filtering settings above. Always save any changes made above before configuring this section.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />'));
                        ?>

												</div>

												<div class="bundle_selection_defaults indented"> <?php 
                        // get normal variation attributes
                        $attributes = $bundled_product->get_variation_attributes();
                        // filtered variation attributes
                        $filtered_attributes = array();
                        // get filter-active setting
                        $filtered = get_post_meta($post->ID, 'filter_variations_' . $item_id, true) == 'yes' ? true : false;
                        // if filter is active, show only the attributes of the selected variations
                        if ($filtered) {
                            foreach ($allowed_variations[$item_id] as $allowed_variation_id) {
                                // get variation meta of allowed variations
                                $product_custom_fields = get_post_custom($allowed_variation_id);
                                foreach ($product_custom_fields as $name => $value) {
                                    if (!strstr($name, 'attribute_')) {
                                        continue;
                                    }
                                    $attribute_name = substr($name, strlen('attribute_'));
                                    if (!isset($filtered_attributes[$attribute_name])) {
                                        $filtered_attributes[$attribute_name][] = $value[0];
                                    } elseif (!in_array($value[0], $filtered_attributes[$attribute_name])) {
                                        $filtered_attributes[$attribute_name][] = $value[0];
                                    }
                                }
                            }
                        }
                        foreach ($attributes as $name => $values) {
                            sort($values);
                            // Get current value for variation (if set)
                            $variation_selected_value = isset($default_attributes[$item_id][sanitize_title($name)]) ? $default_attributes[$item_id][sanitize_title($name)] : '';
                            // Name will be something like attribute_pa_color
                            echo '<select name="default_attributes[' . $item_id . '][' . sanitize_title($name) . ']"><option value="">' . __('No default', 'woocommerce') . ' ' . $woocommerce->attribute_label($name) . '&hellip;</option>';
                            foreach ($values as $value) {
                                // if filters exist, only show the entries available in the filtered_attributes array
                                if ($filtered && isset($filtered_attributes[sanitize_title($name)])) {
                                    if (!in_array($value, $filtered_attributes[sanitize_title($name)]) && !in_array('', $filtered_attributes[sanitize_title($name)])) {
                                        continue;
                                    }
                                }
                                $term = get_term_by('slug', $value, $name);
                                $value_name = $term == false ? '' : $term->name;
                                if (!$value_name) {
                                    $value_name = ucwords($value);
                                }
                                echo '<option ' . selected($variation_selected_value, $value, false) . ' value="' . $value . '">' . apply_filters('woocommerce_variation_option_name', $value_name) . '</option>';
                            }
                            echo '</select>';
                        }
                        ?>

												</div>
											<?php 
                    }
                    $item_quantity = get_post_meta($post->ID, 'bundle_quantity_' . $item_id, true);
                    if (!isset($item_quantity) || $item_quantity < 1 || get_post_meta($product_id, '_downloadable', true) == 'yes' && get_post_meta($product_id, '_virtual', true) == 'yes' && get_option('woocommerce_limit_downloadable_product_qty') == 'yes') {
                        $item_quantity = 1;
                    }
                    ?>

										<div class="quantity">

											<?php 
                    woocommerce_wp_text_input(array('id' => 'bundle_quantity_' . $item_id, 'class' => 'bundle_quantity', 'label' => __('Quantity', 'woocommerce')));
                    ?>

										</div>

										<div class="item_visibility">

											<label for="item_visibility"><?php 
                    _e('Front-End Visibility', 'woo-bundles');
                    ?>
</label>
											<select name="visibility_<?php 
                    echo $item_id;
                    ?>
">
												<?php 
                    $visible = get_post_meta($post->ID, 'visibility_' . $item_id, true) == 'hidden' ? false : true;
                    echo '<option ' . selected($visible, true, false) . ' value="visible">' . __('Visible', 'woo-bundles') . '</option>';
                    echo '<option ' . selected($visible, false, false) . ' value="hidden">' . __('Hidden', 'woo-bundles') . '</option>';
                    echo '<img class="help_tip" data-tip="' . __('Check this option to hide the thumbnail of this bundled product.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />';
                    ?>
											</select>
										</div>

										<div class="images">

											<?php 
                    woocommerce_wp_checkbox(array('id' => 'hide_thumbnail_' . $item_id, 'wrapper_class' => 'hide_thumbnail', 'label' => __('Hide Product Thumbnail', 'woo-bundles'), 'description' => ''));
                    ?>

										</div>

										<div class="override_title">

											<?php 
                    woocommerce_wp_checkbox(array('id' => 'override_title_' . $item_id, 'wrapper_class' => 'override_title', 'label' => __('Override Title', 'woo-bundles'), 'description' => '<img class="help_tip" data-tip="' . __('Check this option to override the default product title.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />'));
                    ?>

										<?php 
                    $item_title = get_post_meta($post->ID, 'product_title_' . $item_id, true);
                    ?>

											<div class="custom_title indented">

												<?php 
                    woocommerce_wp_text_input(array('id' => 'product_title_' . $item_id, 'class' => 'product_title', 'label' => __('Product Title', 'woo-bundles')));
                    ?>

											</div>

										</div>


										<div class="override_description">

											<?php 
                    woocommerce_wp_checkbox(array('id' => 'override_description_' . $item_id, 'wrapper_class' => 'override_description', 'label' => __('Override Short Description', 'woo-bundles'), 'description' => '<img class="help_tip" data-tip="' . __('Check this option to override the default short product description.', 'woo-bundles') . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />'));
                    ?>

										<?php 
                    $item_description = get_post_meta($post->ID, 'product_description_' . $item_id, true);
                    ?>

											<div class="custom_description indented">

												<?php 
                    woocommerce_wp_textarea_input(array('id' => 'product_description_' . $item_id, 'class' => 'product_description', 'label' => __('Product Short Description', 'woo-bundles')));
                    ?>

											</div>

										</div>


									</div>
								</div>
							<?php 
                }
            } else {
                ?>
							<p><label for="bundled_ids_notice"><?php 
                _e('Bundle Configuration', 'woo-bundles');
                ?>
</label></p>
							<p><em><?php 
                _e('To configure additional options, first select some products and then save your changes.', 'woo-bundles');
                ?>
</em></p>
							<?php 
            }
            ?>
					</div> <!-- options group -->
				</div>
				<?php 
        }
 function load_bundle_data()
 {
     global $woocommerce_bundles;
     // stores bundle pricing strategy info and price table
     $this->bundle_price_data = array();
     $this->bundle_price_data['currency_symbol'] = get_woocommerce_currency_symbol();
     $this->bundle_price_data['woocommerce_price_num_decimals'] = (int) get_option('woocommerce_price_num_decimals');
     $this->bundle_price_data['woocommerce_currency_pos'] = get_option('woocommerce_currency_pos');
     $this->bundle_price_data['woocommerce_price_decimal_sep'] = stripslashes(get_option('woocommerce_price_decimal_sep'));
     $this->bundle_price_data['woocommerce_price_thousand_sep'] = stripslashes(get_option('woocommerce_price_thousand_sep'));
     $this->bundle_price_data['woocommerce_price_trim_zeros'] = get_option('woocommerce_price_trim_zeros');
     $this->bundle_price_data['free'] = __('Free!', 'woocommerce');
     $this->bundle_price_data['per_product_pricing'] = $this->per_product_pricing_active;
     $this->bundle_price_data['prices'] = array();
     $this->bundle_price_data['regular_prices'] = array();
     $this->bundle_price_data['total'] = $this->per_product_pricing_active ? (double) 0 : (double) ($this->get_price() == '' ? -1 : $this->get_price());
     $this->bundle_price_data['regular_total'] = $this->per_product_pricing_active ? (double) 0 : (double) $this->regular_price;
     $this->bundle_price_data['total_description'] = __('Total', 'woo-bundles') . ': ';
     $this->bundle_attributes = array();
     $this->available_bundle_variations = array();
     $this->selected_bundle_attributes = array();
     $this->bundled_products = array();
     foreach ($this->bundled_item_ids as $bundled_item_id) {
         // remove suffix
         $sep = explode('_', $bundled_item_id);
         $product_id = $sep[0];
         $bundled_product_post = get_post($product_id);
         if (get_post_status($product_id) != 'publish') {
             continue;
         }
         if ($this->is_wc_v2) {
             $bundled_product = get_product($product_id);
         } else {
             $bundled_product = new WC_Product($product_id);
         }
         $this->bundled_products[$bundled_item_id] = $bundled_product;
         if ($bundled_product->product_type == 'simple') {
             if (!$bundled_product->is_sold_individually()) {
                 $this->sold_individually = false;
             }
             // price for simple products gets stored now, for variable products jquery gets the job done
             $this->bundle_price_data['prices'][$bundled_product->id] = (double) $bundled_product->get_price();
             $this->bundle_price_data['regular_prices'][$bundled_product->id] = (double) $bundled_product->regular_price;
             // no variation data to load - product is simple
             $this->min_bundle_price = $this->min_bundle_price + $this->bundled_item_quantities[$bundled_item_id] * $bundled_product->get_price();
             $this->min_bundle_regular_price = $this->min_bundle_regular_price + $this->bundled_item_quantities[$bundled_item_id] * $bundled_product->regular_price;
             $this->max_bundle_price = $this->max_bundle_price + $this->bundled_item_quantities[$bundled_item_id] * $bundled_product->get_price();
             $this->max_bundle_regular_price = $this->max_bundle_regular_price + $this->bundled_item_quantities[$bundled_item_id] * $bundled_product->regular_price;
         } elseif ($bundled_product->product_type == 'variable') {
             // prepare price variable for jquery
             $this->bundle_price_data['prices'][$bundled_item_id] = 0;
             $this->bundle_price_data['regular_prices'][$bundled_item_id] = 0;
             // get all available attributes and settings
             $this->bundle_attributes[$bundled_item_id] = $bundled_product->get_variation_attributes();
             $default_product_attributes = array();
             if ($this->bundle_defaults_active[$bundled_item_id]) {
                 $default_product_attributes = $this->bundle_defaults[$bundled_item_id];
             } else {
                 $default_product_attributes = (array) maybe_unserialize(get_post_meta($bundled_product_post->ID, '_default_attributes', true));
             }
             $this->selected_bundle_attributes[$bundled_item_id] = apply_filters('woocommerce_product_default_attributes', $default_product_attributes);
             // calculate min-max variation prices
             $min_variation_regular_price = '';
             $min_variation_sale_price = '';
             $max_variation_regular_price = '';
             $max_variation_sale_price = '';
             foreach ($bundled_product->get_children() as $child_id) {
                 $variation = $bundled_product->get_child($child_id);
                 // stop here if this variation is not within the active set (prices will not include this variation)
                 if ($this->variation_filters_active[$bundled_item_id]) {
                     if (!is_array($this->allowed_variations[$bundled_item_id])) {
                         continue;
                     }
                     if (!in_array($child_id, $this->allowed_variations[$bundled_item_id])) {
                         continue;
                     }
                 }
                 if ($variation instanceof WC_Product_Variation) {
                     if (get_post_status($variation->get_variation_id()) != 'publish') {
                         continue;
                     }
                     // Disabled
                     if (!$variation->is_sold_individually()) {
                         $this->sold_individually = false;
                     }
                     // variation min-max price calculation
                     $variation_price = get_post_meta($child_id, '_price', true);
                     $variation_sale_price = get_post_meta($child_id, '_sale_price', true);
                     // Low price
                     if (!is_numeric($min_variation_regular_price) || $variation_price < $min_variation_regular_price) {
                         $min_variation_regular_price = $variation_price;
                     }
                     if ($variation_sale_price !== '' && (!is_numeric($min_variation_sale_price) || $variation_sale_price < $min_variation_sale_price)) {
                         $min_variation_sale_price = $variation_sale_price;
                     }
                     // High price
                     if (!is_numeric($max_variation_regular_price) || $variation_price > $max_variation_regular_price) {
                         $max_variation_regular_price = $variation_price;
                     }
                     if ($variation_sale_price !== '' && (!is_numeric($max_variation_sale_price) || $variation_sale_price > $max_variation_sale_price)) {
                         $max_variation_sale_price = $variation_sale_price;
                     }
                     // prepare available options
                     $variation_attributes = $variation->get_variation_attributes();
                     $availability = $variation->get_availability();
                     if (!is_admin() && !$woocommerce_bundles->validate_stock($product_id, $variation->variation_id, get_post_meta($this->id, 'bundle_quantity_' . $bundled_item_id, true), true, true)) {
                         $availability = array('availability' => __('Out of stock', 'woocommerce'), 'class' => 'out-of-stock');
                     }
                     $availability_html = !empty($availability['availability']) ? apply_filters('woocommerce_stock_html', '<p class="stock ' . $availability['class'] . '">' . $availability['availability'] . '</p>', $availability['availability']) : '';
                     if (has_post_thumbnail($variation->get_variation_id())) {
                         $attachment_id = get_post_thumbnail_id($variation->get_variation_id());
                         $attachment = wp_get_attachment_image_src($attachment_id, apply_filters('bundled_product_large_thumbnail_size', 'shop_single'));
                         $image = $attachment ? current($attachment) : '';
                         $attachment = wp_get_attachment_image_src($attachment_id, 'full');
                         $image_link = $attachment ? current($attachment) : '';
                         $image_title = get_the_title($attachment_id);
                     } else {
                         $image = $image_link = $image_title = '';
                     }
                     $this->available_bundle_variations[$bundled_item_id][] = apply_filters('woocommerce_available_variation', array('variation_id' => $variation->get_variation_id(), 'product_id' => $bundled_item_id, 'attributes' => $variation_attributes, 'image_src' => $image, 'image_link' => $image_link, 'image_title' => $image_title, 'price' => (double) $variation->get_price(), 'regular_price' => (double) $variation->regular_price, 'price_html' => $this->per_product_pricing_active ? '<span class="price">' . $variation->get_price_html() . '</span>' : '', 'availability_html' => $availability_html), $bundled_product, $variation);
                 }
             }
             $add = $min_variation_sale_price === '' || $min_variation_regular_price < $min_variation_sale_price ? $min_variation_regular_price : $min_variation_sale_price;
             $this->min_bundle_price = $this->min_bundle_price + $this->bundled_item_quantities[$bundled_item_id] * $add;
             $this->min_bundle_regular_price = $this->min_bundle_regular_price + $this->bundled_item_quantities[$bundled_item_id] * $min_variation_regular_price;
             $add = $max_variation_sale_price === '' || $max_variation_regular_price < $max_variation_sale_price ? $max_variation_regular_price : $max_variation_sale_price;
             $this->max_bundle_price = $this->max_bundle_price + $this->bundled_item_quantities[$bundled_item_id] * $add;
             $this->max_bundle_regular_price = $this->max_bundle_regular_price + $this->bundled_item_quantities[$bundled_item_id] * $max_variation_regular_price;
         }
     }
 }
/** Modified Function - create matrix for row -- 03/02/2016 **/
function woocommerce_bulk_variations_create_matrix_v24($post_id)
{
    // 2.0 Compat
    if (function_exists('get_product')) {
        $_product = get_product($post_id);
    } else {
        $_product = new WC_Product($post_id);
    }
    $attributes = $_product->get_attributes();
    //Get first attribute -- 03/02/2016
    if (is_array($attributes) && count($attributes) > 0) {
        foreach ($attributes as $att) {
            $row_attribute = $att['name'];
            break;
        }
    }
    $av_temp = $_product->get_variation_attributes();
    $av = array();
    if (isset($attributes[$row_attribute]) && $attributes[$row_attribute]['is_taxonomy']) {
        $row_term_values = WC_Bulk_Variations_Compatibility::wc_get_product_terms($post_id, $row_attribute, 'all');
        foreach ($row_term_values as $row_term_value) {
            if (in_array($row_term_value->slug, $av_temp[$row_attribute])) {
                $av[$row_attribute][] = $row_term_value->slug;
            }
        }
    } else {
        $av[$row_attribute] = $av_temp[$row_attribute];
    }
    $grid = array();
    foreach ($av[$row_attribute] as $row_value) {
        $grid[$row_value] = null;
    }
    //Now sanitize the attributes, since $product->get_available_variations returns the variations sanitized, but get_variation_attributes does not
    $row_attribute = sanitize_title($row_attribute);
    $pv = $_product->get_available_variations();
    $filter = new WC_Bulk_Variation_Array_Filter('attribute_' . $row_attribute, $pv);
    foreach ($grid as $row_key => &$field_value) {
        $field_value = $filter->get_matches($row_key);
    }
    $matrix_data = array('row_attribute' => $row_attribute, 'matrix_rows' => array_values($av[$row_attribute]), 'matrix' => $grid);
    return $matrix_data;
}
Example #11
0
/**
 * Build a Google Shopping Content Product from a WC Product
 * @param WC_Product $wc_product
 * @return Google_Service_ShoppingContent_Product
 */
function woogle_build_product($wc_product)
{
    // Create Google Shopping Content Product
    require_once plugin_dir_path(woogle_get_plugin_file()) . 'vendor/google-api-php-client/src/Google/Service/ShoppingContent.php';
    $product = new Google_Service_ShoppingContent_Product();
    // Custom Attributes
    $product_custom_attributes = array();
    // Product identifiers
    $sku = $wc_product->get_sku();
    if (empty($sku)) {
        if ($wc_product->is_type('variation')) {
            $product->setOfferId($wc_product->variation_id);
        } else {
            $product->setOfferId($wc_product->id);
        }
    } else {
        $product->setOfferId($sku);
    }
    if ($wc_product->is_type('variation')) {
        $product->setItemGroupId($wc_product->parent->id);
    }
    $woocommerce_id_attribute = new Google_Service_ShoppingContent_ProductCustomAttribute();
    $woocommerce_id_attribute->setName('woocommerce_id');
    $woocommerce_id_attribute->setValue($wc_product->id);
    $woocommerce_id_attribute->setType('int');
    $product_custom_attributes[] = $woocommerce_id_attribute;
    // Title
    $woogle_title = get_post_meta($wc_product->id, '_woogle_title', true);
    if (!empty($woogle_title)) {
        $product->setTitle(html_entity_decode(strip_tags($woogle_title)));
    } else {
        $product->setTitle(html_entity_decode(strip_tags($wc_product->get_title())));
    }
    // Description
    $woogle_description = get_post_meta($wc_product->id, '_woogle_description', true);
    if (!empty($woogle_description)) {
        $product->setDescription(html_entity_decode(strip_tags($woogle_description)));
    } else {
        $product->setDescription(html_entity_decode(strip_tags($wc_product->post->post_content)));
    }
    $product->setLink($wc_product->get_permalink());
    $image = $wc_product->get_image();
    $post_thumbnail_id = get_post_thumbnail_id($wc_product->id);
    if ($post_thumbnail_id) {
        $image_src = wp_get_attachment_image_src($post_thumbnail_id);
        $product->setImageLink(@$image_src[0]);
    }
    $product->setContentLanguage(substr(get_locale(), 0, 2));
    $product->setTargetCountry(WC()->countries->get_base_country());
    $product->setChannel('online');
    $product->setAvailability($wc_product->is_in_stock() ? 'in stock' : 'out of stock');
    // Condition
    $condition = get_post_meta($wc_product->id, '_woogle_condition', true);
    if (!empty($condition)) {
        $product->setCondition($condition);
    } else {
        $product->setcondition('new');
    }
    // Category
    $category = get_post_meta($wc_product->id, '_woogle_category', true);
    if (!empty($category)) {
        $product->setGoogleProductCategory($category);
    }
    // Brand
    $brand = get_post_meta($wc_product->id, '_woogle_brand', true);
    if (!empty($brand)) {
        $product->setBrand($brand);
    }
    // GTIN
    $gtin = get_post_meta($wc_product->id, '_woogle_gtin', true);
    if (!empty($gtin)) {
        $product->setGtin($gtin);
    }
    // MPN
    $mpn = get_post_meta($wc_product->id, '_woogle_mpn', true);
    if (!empty($mpn)) {
        $product->setMpn($mpn);
    }
    if (empty($gtin) && empty($mpn)) {
        $product->setIdentifierExists(false);
    }
    // Price
    $price = new Google_Service_ShoppingContent_Price();
    $price->setValue($wc_product->get_regular_price());
    $price->setCurrency(get_woocommerce_currency());
    $product->setPrice($price);
    // Sale price
    $wc_sale_price = $wc_product->get_sale_price();
    if (!empty($wc_sale_price)) {
        $sale_price = new Google_Service_ShoppingContent_Price();
        $sale_price->setValue($wc_sale_price);
        $sale_price->setCurrency(get_woocommerce_currency());
        $product->setSalePrice($sale_price);
        $post_id = $wc_product->is_type('variation') ? $wc_product->variation_id : $wc_product->id;
        $sale_price_dates_from = get_post_meta($post_id, '_sale_price_dates_from', true);
        $sale_price_dates_to = get_post_meta($post_id, '_sale_price_dates_to', true);
        if (!empty($sale_price_dates_from) && !empty($sale_price_dates_to)) {
            $effective_date_start = date('c', intval($sale_price_dates_from));
            $effective_date_end = date('c', intval($sale_price_dates_to));
            $product->setSalePriceEffectiveDate("{$effective_date_start}/{$effective_date_end}");
        }
    }
    // Shipping fields
    // Shipping weight
    $wc_product_weight = $wc_product->get_weight();
    if (!empty($wc_product_weight)) {
        $shipping_weight = new Google_Service_ShoppingContent_ProductShippingWeight();
        $shipping_weight->setValue($wc_product_weight);
        $shipping_weight->setUnit(get_option('woocommerce_weight_unit', 'kg'));
        $product->setShippingWeight($shipping_weight);
    }
    // Shipping dimensions
    $wc_dimension_unit = get_option('woocommerce_dimension_unit', 'cm');
    $wc_product_length = $wc_product->get_length();
    if (!empty($wc_product_length)) {
        $dimension = new Google_Service_ShoppingContent_ProductShippingDimension();
        $dimension->setValue($wc_product_length);
        $dimension->setUnit($wc_dimension_unit);
        $product->setShippingLength($dimension);
    }
    $wc_product_width = $wc_product->get_width();
    if (!empty($wc_product_width)) {
        $dimension = new Google_Service_ShoppingContent_ProductShippingDimension();
        $dimension->setValue($wc_product_width);
        $dimension->setUnit($wc_dimension_unit);
        $product->setShippingWidth($dimension);
    }
    $wc_product_height = $wc_product->get_height();
    if (!empty($wc_product_height)) {
        $dimension = new Google_Service_ShoppingContent_ProductShippingDimension();
        $dimension->setValue($wc_product_height);
        $dimension->setUnit($wc_dimension_unit);
        $product->setShippingHeight($dimension);
    }
    // Attributes
    $color = null;
    $material = null;
    $pattern = null;
    $size = null;
    $age_group = null;
    $gender = null;
    $adult = null;
    if ($wc_product->is_type('variation')) {
        // Variable product
        $wc_variation_attributes = $wc_product->get_variation_attributes();
        foreach ($wc_variation_attributes as $name => $value) {
            if (!empty($value)) {
                $attribute = new Google_Service_ShoppingContent_ProductCustomAttribute();
                $attribute->setName($name);
                $attribute->setValue($value);
                $attribute->setType('text');
                $product_custom_attributes[] = $attribute;
                // Google attributes
                if (empty($color)) {
                    $color = woogle_maybe_get_attribute('color', $name, $value);
                }
                if (empty($material)) {
                    $material = woogle_maybe_get_attribute('material', $name, $value);
                }
                if (empty($pattern)) {
                    $pattern = woogle_maybe_get_attribute('pattern', $name, $value);
                }
                if (empty($size)) {
                    $size = woogle_maybe_get_attribute('size', $name, $value);
                }
                if (empty($age_group)) {
                    $age_group = woogle_maybe_get_attribute('age-group', $name, $value);
                }
                if (empty($gender)) {
                    $gender = woogle_maybe_get_attribute('gender', $name, $value);
                }
                if (empty($adult)) {
                    $adult = woogle_maybe_get_attribute('adult', $name, $value);
                }
            }
        }
    } else {
        // Simple product
        $wc_attributes = $wc_product->get_attributes();
        foreach ($wc_attributes as $name => $wc_attribute) {
            if ($wc_attribute['is_taxonomy']) {
                $term_values = array();
                $terms = wp_get_post_terms($wc_product->id, $name);
                foreach ($terms as $term) {
                    $term_values[] = $term->slug;
                }
                if (!empty($term_values)) {
                    $value = implode(',', $term_values);
                    $attribute = new Google_Service_ShoppingContent_ProductCustomAttribute();
                    $attribute->setName($name);
                    $attribute->setValue($value);
                    $attribute->setType('text');
                    $product_custom_attributes[] = $attribute;
                    // Google attributes
                    if (empty($color)) {
                        $color = woogle_maybe_get_attribute('color', $name, $value);
                    }
                    if (empty($material)) {
                        $material = woogle_maybe_get_attribute('material', $name, $value);
                    }
                    if (empty($pattern)) {
                        $pattern = woogle_maybe_get_attribute('pattern', $name, $value);
                    }
                    if (empty($size)) {
                        $size = woogle_maybe_get_attribute('size', $name, $value);
                    }
                    if (empty($age_group)) {
                        $age_group = woogle_maybe_get_attribute('age-group', $name, $value);
                    }
                    if (empty($gender)) {
                        $gender = woogle_maybe_get_attribute('gender', $name, $value);
                    }
                    if (empty($adult)) {
                        $adult = woogle_maybe_get_attribute('adult', $name, $value);
                    }
                }
            }
        }
    }
    /*
     * Physical properties
     */
    // Color
    if (empty($color)) {
        $color = get_post_meta($wc_product->id, '_woogle_color', true);
    }
    if (!empty($color)) {
        $product->setColor($color);
    }
    // Material
    if (empty($material)) {
        $material = get_post_meta($wc_product->id, '_woogle_material', true);
    }
    if (!empty($material)) {
        $product->setMaterial($material);
    }
    // Pattern
    if (empty($pattern)) {
        $pattern = get_post_meta($wc_product->id, '_woogle_pattern', true);
    }
    if (!empty($pattern)) {
        $product->setPattern($pattern);
    }
    // Size
    if (empty($size)) {
        $size = get_post_meta($wc_product->id, '_woogle_size', true);
    }
    if (!empty($size)) {
        $product->setSizes(explode(', ', $size));
        $product->setSizeSystem(WC()->countries->get_base_country());
    }
    /*
     * Target consumer
     */
    // Age Group
    if (empty($age_group)) {
        $age_group = get_post_meta($wc_product->id, '_woogle_age_group', true);
    }
    if (!empty($age_group)) {
        $product->setAgeGroup($age_group);
    }
    // Gender
    if (empty($gender)) {
        $gender = get_post_meta($wc_product->id, '_woogle_gender', true);
    }
    if (!empty($gender)) {
        $product->setGender($gender);
    }
    // Gender
    if (empty($adult)) {
        $adult = get_post_meta($wc_product->id, '_woogle_adult', true);
    }
    if (!empty($adult) && $adult != 'no') {
        $product->setAdult(true);
    }
    $product->setCustomAttributes($product_custom_attributes);
    return $product;
}