*/
// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit;
}
?>
<label class="bundled_product_optional_checkbox">
	<input class="bundled_product_checkbox" type="checkbox" name="<?php 
echo $bundle_fields_prefix;
?>
bundle_selected_optional_<?php 
echo $bundled_item->item_id;
?>
" value="" <?php 
checked($bundled_item->is_optional_checked() && !$bundled_item->is_out_of_stock(), true);
echo $bundled_item->is_out_of_stock() ? 'disabled="disabled"' : '';
?>
 /> <?php 
$price_html = $bundled_item->product->get_price_html();
$label_price = $bundled_item->is_priced_per_product() && $price_html ? sprintf(__(' for %s', 'woocommerce-product-bundles'), $price_html) : '';
$label_title = $bundled_item->get_title() === '' ? sprintf(__(' &quot;%s&quot;', 'woocommerce-product-bundles'), WC_PB_Helpers::format_product_shop_title($bundled_item->get_raw_title(), $quantity > 1 && $bundled_item->get_quantity('max') === $quantity ? $quantity : '')) : '';
$label_stock_status = '';
if ($bundled_item->is_out_of_stock()) {
    $availability = $bundled_item->get_availability();
    $availability_html = empty($availability['availability']) ? '' : esc_html($availability['availability']);
    $label_stock_status = sprintf(_x(' &mdash; %s', 'optional label stock status', 'woocommerce-product-bundles'), '<span class="bundled_item_stock_label">' . $availability_html . '</span>');
}
echo sprintf(__('Add%1$s%2$s%3$s', 'woocommerce-product-bundles'), $label_title, $label_price, $label_stock_status);
?>
</label>
<?php

/**
 * Bundled Item Title Template.
 *
 * Override this template by copying it to 'yourtheme/woocommerce/single-product/bundled-item-title.php'.
 *
 * On occasion, this template file may need to be updated and you (the theme developer) will need to copy the new files to your theme to maintain compatibility.
 * We try to do this as little as possible, but it does happen.
 * When this occurs the version of the template file will be bumped and the readme will list any important changes.
 *
 * Note: Bundled product properties are accessible via '$bundled_item->product'.
 *
 * @version 4.9.5
 */
// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit;
}
if ($title === '') {
    return;
}
?>
<h4 class="bundled_product_title product_title"><?php 
$optional = $optional ? apply_filters('woocommerce_bundles_optional_bundled_item_suffix', __('optional', 'woocommerce-product-bundles'), $bundled_item, $bundle) : '';
echo '<span class="bundled_product_title_inner">' . WC_PB_Helpers::format_product_shop_title($title, $quantity, '', $optional) . '</span>';
?>
</h4>
 /**
  * Calculate subscriptions price html component by breaking up bundled subs into recurring scheme groups and adding up all prices in each group.
  *
  * @return string
  */
 public function apply_subs_price_html($price)
 {
     if (!empty($this->bundled_items)) {
         $subs_details = array();
         $subs_details_html = array();
         $non_optional_subs_exist = false;
         foreach ($this->bundled_items as $bundled_item_id => $bundled_item) {
             if ($bundled_item->is_sub()) {
                 $bundled_product = $bundled_item->product;
                 if ($bundled_item->is_variable_sub()) {
                     $product_id = get_post_meta($bundled_product->id, '_min_price_variation_id', true);
                     $product = $bundled_product->get_child($product_id);
                 } else {
                     $product = $bundled_product;
                 }
                 $sub_string = str_replace('_synced', '', WC_Subscriptions_Cart::get_recurring_cart_key(array('data' => $product), ' '));
                 if (!isset($subs_details[$sub_string]['bundled_items'])) {
                     $subs_details[$sub_string]['bundled_items'] = array();
                 }
                 if (!isset($subs_details[$sub_string]['price'])) {
                     $subs_details[$sub_string]['price'] = 0;
                     $subs_details[$sub_string]['regular_price'] = 0;
                     $subs_details[$sub_string]['is_range'] = false;
                 }
                 $subs_details[$sub_string]['bundled_items'][] = $bundled_item_id;
                 $subs_details[$sub_string]['price'] += $this->bundled_quantities_index['min'][$bundled_item_id] * WC_PB_Helpers::get_product_display_price($product, $bundled_item->min_recurring_price);
                 $subs_details[$sub_string]['regular_price'] += $this->bundled_quantities_index['min'][$bundled_item_id] * WC_PB_Helpers::get_product_display_price($product, $bundled_item->min_regular_recurring_price);
                 if ($bundled_item->is_variable_sub()) {
                     if ($bundled_product->min_variation_price !== $bundled_product->max_variation_price || $bundled_product->subscription_period !== $bundled_product->max_variation_period || $bundled_product->subscription_period_interval !== $bundled_product->max_variation_period_interval) {
                         $subs_details[$sub_string]['is_range'] = true;
                     }
                 }
                 if (!isset($subs_details[$sub_string]['price_html'])) {
                     $subs_details[$sub_string]['price_html'] = WC_PB_Helpers::get_recurring_price_html_component($product);
                 }
             }
         }
         if (!empty($subs_details)) {
             foreach ($subs_details as $sub_details) {
                 if ($sub_details['price'] > 0) {
                     $sub_price_html = wc_price($sub_details['price']);
                     if ($sub_details['price'] !== $sub_details['regular_price']) {
                         $sub_regular_price_html = wc_price($sub_details['regular_price']);
                         if ($sub_details['is_range']) {
                             $sub_price_html = sprintf(_x('%1$s%2$s', 'Price range: from', 'woocommerce-product-bundles'), _x('<span class="from">from </span>', 'min-price', 'woocommerce-product-bundles'), $this->get_price_html_from_to($sub_regular_price_html, $sub_price_html));
                         } else {
                             $sub_price_html = $this->get_price_html_from_to($sub_regular_price_html, $sub_price_html);
                         }
                     } elseif ($sub_details['price'] == 0 && !$sub_details['is_range']) {
                         $sub_price_html = __('Free!', 'woocommerce');
                     } else {
                         if ($sub_details['is_range']) {
                             $sub_price_html = sprintf(_x('%1$s%2$s', 'Price range: from', 'woocommerce-product-bundles'), _x('<span class="from">from </span>', 'min-price', 'woocommerce-product-bundles'), $sub_price_html);
                         }
                     }
                     $sub_price_html = sprintf($sub_details['price_html'], $sub_price_html);
                     $subs_details_html[] = '<span class="bundled_sub_price_html">' . $sub_price_html . '</span>';
                 }
             }
             $price_html = implode('<span class="plus"> + </span>', $subs_details_html);
             if ($this->min_bundle_regular_price != 0) {
                 $price = sprintf(_x('%1$s<span class="bundled_subscriptions_price_html" %2$s> now,</br>then %3$s</span>', 'subscription price html suffix', 'woocommerce-product-bundles'), $price, !empty($subs_details_html) ? '' : 'style="display:none"', $price_html);
             } else {
                 $price = '<span class="bundled_subscriptions_price_html">' . $price_html . '</span>';
             }
         }
     }
     return $price;
 }
 /**
  * Tweak bundle container name.
  *
  * @param  bool 	$show
  * @param  array 	$cart_item
  * @param  string 	$cart_item_key
  * @return bool
  */
 public function woo_bundles_cart_widget_container_item_name($name, $cart_item, $cart_item_key)
 {
     if (isset($cart_item['bundled_items'])) {
         $name = WC_PB_Helpers::format_product_shop_title($name, $cart_item['quantity']);
     }
     return $name;
 }
 /**
  * Order API Modification #3 (unused):
  *
  * Exclude/modify order items depending on the "per-item pricing" and "per-item shipping" settings.
  *
  * @param  array    $items
  * @param  WC_Order $order
  * @return array
  */
 public function order_items($items, $order)
 {
     $return_items = $items;
     if (false === self::$override_order_items_filters && apply_filters('woocommerce_bundles_filter_order_items', false, $order)) {
         $return_items = array();
         foreach ($items as $item_id => $item) {
             if (isset($item['bundled_items']) && isset($item['bundle_cart_key'])) {
                 /*
                  * Do not export bundled items that are shipped packaged in the container ("bundled" shipping).
                  * Instead, add their totals into the container and create a container "Contents" meta field to provide a description of the included products.
                  */
                 if (isset($item['per_product_shipping']) && $item['per_product_shipping'] === 'no') {
                     $bundle_key = $item['bundle_cart_key'];
                     // Aggregate contents
                     $meta_key = __('Contents', 'woocommerce-product-bundles');
                     $meta_values = array();
                     // Aggregate prices
                     $bundle_totals = array('line_subtotal' => $item['line_subtotal'], 'line_total' => $item['line_total'], 'line_subtotal_tax' => $item['line_subtotal_tax'], 'line_tax' => $item['line_tax'], 'line_tax_data' => maybe_unserialize($item['line_tax_data']));
                     foreach ($items as $child_item_id => $child_item) {
                         if (isset($child_item['bundled_by']) && $child_item['bundled_by'] === $bundle_key && isset($child_item['bundled_shipping']) && $child_item['bundled_shipping'] === 'no') {
                             /*
                              * Aggregate bundled items shipped within the container as "Contents" meta of container.
                              */
                             $child = $order->get_product_from_item($child_item);
                             if (!$child) {
                                 continue;
                             }
                             $sku = $child->get_sku();
                             if (!$sku) {
                                 $sku = '#' . (isset($child->variation_id) ? $child->variation_id : $child->id);
                             }
                             $title = WC_PB_Helpers::format_product_shop_title($child_item['name'], $child_item['qty']);
                             $meta = '';
                             if (!empty($child_item['item_meta'])) {
                                 if (!empty($child_item['item_meta'][__('Part of', 'woocommerce-product-bundles')])) {
                                     unset($child_item['item_meta'][__('Part of', 'woocommerce-product-bundles')]);
                                 }
                                 if (WC_PB_Core_Compatibility::is_wc_version_gte_2_4()) {
                                     $item_meta = new WC_Order_Item_Meta($child_item);
                                 } else {
                                     $item_meta = new WC_Order_Item_Meta($child_item['item_meta']);
                                 }
                                 $formatted_meta = $item_meta->display(true, true, '_', ', ');
                                 if ($formatted_meta) {
                                     $meta = $formatted_meta;
                                 }
                             }
                             $meta_values[] = WC_PB_Helpers::format_product_title($title, $sku, $meta, true);
                             /*
                              * Aggregate the totals of bundled items shipped within the container into the container price.
                              */
                             $bundle_totals['line_subtotal'] += $child_item['line_subtotal'];
                             $bundle_totals['line_total'] += $child_item['line_total'];
                             $bundle_totals['line_subtotal_tax'] += $child_item['line_subtotal_tax'];
                             $bundle_totals['line_tax'] += $child_item['line_tax'];
                             $child_item_line_tax_data = maybe_unserialize($child_item['line_tax_data']);
                             $bundle_totals['line_tax_data']['total'] = array_merge($bundle_totals['line_tax_data']['total'], $child_item_line_tax_data['total']);
                         }
                     }
                     $items[$item_id]['line_tax_data'] = serialize($bundle_totals['line_tax_data']);
                     $items[$item_id] = array_merge($item, $bundle_totals);
                     if (WC_PB_Core_Compatibility::is_wc_version_gte_2_4()) {
                         // Terrible hack: add an element in the 'item_meta_array' array.
                         // A puppy somewhere just died.
                         if (!empty($items[$item_id]['item_meta_array'])) {
                             $keys = array_keys($items[$item_id]['item_meta_array']);
                             $last_key = end($keys);
                             $entry = new stdClass();
                             $entry->key = $meta_key;
                             $entry->value = implode(', ', $meta_values);
                             $items[$item_id]['item_meta_array'][$last_key + 1] = $entry;
                         }
                     }
                     $items[$item_id]['item_meta'][$meta_key] = implode(', ', $meta_values);
                     $return_items[$item_id] = $items[$item_id];
                     /*
                      * If the bundled items are shipped individually ("per-item" shipping), do not export the container unless it has a non-zero price.
                      * In this case, instead of marking it as virtual, modify its weight and dimensions (tiny values) to avoid any extra shipping costs and ensure that its value is included in the shipment - @see get_product_from_item
                      */
                 } elseif ($item['line_total'] > 0) {
                     $return_items[$item_id] = $items[$item_id];
                 }
             } elseif (isset($item['bundled_by']) && isset($item['bundle_cart_key'])) {
                 if (!isset($item['bundled_shipping']) || $item['bundled_shipping'] === 'yes') {
                     $return_items[$item_id] = $items[$item_id];
                 }
             } else {
                 $return_items[$item_id] = $items[$item_id];
             }
         }
     }
     return $return_items;
 }
 /**
  * Remove price filters after modifying child product prices depending on the per-product pricing option state, including any discounts defined at bundled item level.
  *
  * @return  void
  */
 public function remove_price_filters()
 {
     WC_PB_Helpers::remove_price_filters();
 }
 /**
  * Remove price filters after modifying child product prices depending on the per-product pricing option state, including any discounts defined at bundled item level.
  *
  * @return  void
  */
 public static function remove_price_filters()
 {
     self::$bundled_item = false;
     remove_filter('woocommerce_get_price', array(__CLASS__, 'filter_get_price'), 15, 2);
     remove_filter('woocommerce_get_sale_price', array(__CLASS__, 'filter_get_sale_price'), 15, 2);
     remove_filter('woocommerce_get_regular_price', array(__CLASS__, 'filter_get_regular_price'), 15, 2);
     remove_filter('woocommerce_get_price_html', array(__CLASS__, 'filter_get_price_html'), 10, 2);
     remove_filter('woocommerce_show_variation_price', array(__CLASS__, 'filter_show_variation_price'), 10, 3);
     remove_filter('woocommerce_get_variation_price_html', array(__CLASS__, 'filter_get_price_html'), 10, 2);
     remove_filter('woocommerce_variation_prices', array(__CLASS__, 'filter_get_variation_prices'), 10, 3);
 }