function __construct($product_id, $component_id, $parent)
 {
     $this->product = WC_CP_Core_Compatibility::wc_get_product($product_id);
     if ($this->product) {
         $this->component_data = $parent->get_component_data($component_id);
         $this->component_id = $component_id;
         $this->per_product_pricing = $parent->is_priced_per_product();
         $this->composite_id = $parent->id;
         $this->add_filters();
         $this->init();
         $this->remove_filters();
     }
 }
Пример #2
0
 /**
  * Adds configuration-specific cart-item data.
  *
  * @param  array 	$cart_item_data
  * @param  int 		$product_id
  * @return void
  */
 function wc_cp_add_cart_item_data($cart_item_data, $product_id)
 {
     global $woocommerce_composite_products;
     // Get product type
     $terms = get_the_terms($product_id, 'product_type');
     $product_type = !empty($terms) && isset(current($terms)->name) ? sanitize_title(current($terms)->name) : 'simple';
     if ($product_type === 'composite' && isset($_REQUEST['wccp_component_selection']) && is_array($_REQUEST['wccp_component_selection'])) {
         // Create a unique array with the composite configuration
         $composite_config = array();
         // Get composite data
         $composite = WC_CP_Core_Compatibility::wc_get_product($product_id);
         $composite_data = $composite->get_composite_data();
         foreach ($_REQUEST['wccp_component_selection'] as $component_id => $composited_product_id) {
             $composited_product_quantity = isset($_REQUEST['wccp_component_quantity'][$component_id]) ? absint($_REQUEST['wccp_component_quantity'][$component_id]) : absint($composite_data[$component_id]['quantity_min']);
             if ($composited_product_id) {
                 $composited_product_wrapper = $composite->get_composited_product($component_id, $composited_product_id);
                 if (!$composited_product_wrapper) {
                     continue;
                 }
                 $composited_product = $composited_product_wrapper->get_product();
                 $composited_product_type = $composited_product->product_type;
                 if ($composited_product->sold_individually === 'yes' && $composited_product_quantity > 1) {
                     $composited_product_quantity = 1;
                 }
             }
             $composite_config[$component_id]['product_id'] = $composited_product_id;
             $composite_config[$component_id]['composite_id'] = $product_id;
             $composite_config[$component_id]['quantity'] = $composited_product_quantity;
             $composite_config[$component_id]['title'] = $composite_data[$component_id]['title'];
             $composite_config[$component_id]['quantity_min'] = $composite_data[$component_id]['quantity_min'];
             $composite_config[$component_id]['quantity_max'] = $composite_data[$component_id]['quantity_max'];
             $composite_config[$component_id]['discount'] = isset($composite_data[$component_id]['discount']) ? $composite_data[$component_id]['discount'] : 0;
             $composite_config[$component_id]['optional'] = $composite_data[$component_id]['optional'];
             // Continue when selected product is 'None'
             if (!$composited_product_id || $composited_product_id === '' || $composited_product_quantity === 0) {
                 $composite_config[$component_id]['type'] = 'none';
                 $composite_config[$component_id]['price'] = 0;
                 continue;
             } else {
                 $composite_config[$component_id]['type'] = $composited_product_type;
             }
             if ($composited_product_type === 'variable') {
                 $attributes_config = array();
                 $attributes = (array) maybe_unserialize(get_post_meta($composited_product_id, '_product_attributes', true));
                 foreach ($attributes as $attribute) {
                     if (!$attribute['is_variation']) {
                         continue;
                     }
                     $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
                     // has already been checked for validity in function 'wc_cp_validation'
                     $value = sanitize_title(trim(stripslashes($_REQUEST['wccp_' . $taxonomy][$component_id])));
                     if ($attribute['is_taxonomy']) {
                         $attributes_config[$taxonomy] = $value;
                     } else {
                         // For custom attributes, get the name from the slug
                         $options = array_map('trim', explode(WC_DELIMITER, $attribute['value']));
                         foreach ($options as $option) {
                             if (sanitize_title($option) == $value) {
                                 $value = $option;
                                 break;
                             }
                         }
                         $attributes_config[$taxonomy] = $value;
                     }
                 }
                 $composite_config[$component_id]['variation_id'] = $_REQUEST['wccp_variation_id'][$component_id];
                 $composite_config[$component_id]['attributes'] = $attributes_config;
             }
             $composited_product_variation_id = isset($composite_config[$component_id]['variation_id']) ? $composite_config[$component_id]['variation_id'] : '';
             $composite_config[$component_id]['price'] = $this->wc_cp_get_composited_product_price($composited_product_id, $composited_product_variation_id, $component_id, $composite);
             $composite_config[$component_id] = apply_filters('woocommerce_composite_component_cart_item_identifier', $composite_config[$component_id], $component_id);
         }
         $cart_item_data['composite_data'] = $composite_config;
         // Prepare additional data for later use
         $cart_item_data['composite_children'] = array();
         return $cart_item_data;
     } else {
         return $cart_item_data;
     }
 }
Пример #3
0
 /**
  * Return a formatted product title based on variation id.
  *
  * @param  int    $item_id
  * @return string
  */
 public function get_product_variation_title($variation_id)
 {
     if (is_object($variation_id)) {
         $variation = $variation_id;
     } else {
         $variation = WC_CP_Core_Compatibility::wc_get_product($variation_id);
     }
     if (!$variation) {
         return false;
     }
     $description = wc_get_formatted_variation($variation->get_variation_attributes(), true);
     $title = $variation->get_title();
     $sku = $variation->get_sku();
     if ($sku) {
         $identifier = $sku;
     } else {
         $identifier = '#' . $variation->variation_id;
     }
     return $this->format_product_title($title, $identifier, $description);
 }
 /**
  * Search for component options and echo json.
  *
  * @param   string $x (default: '')
  * @param   string $post_types (default: array('product'))
  * @return  void
  */
 public function json_search_component_options($x = 'default', $post_types = array('product'))
 {
     global $woocommerce_composite_products;
     ob_start();
     check_ajax_referer('search-products', 'security');
     $term = (string) wc_clean(stripslashes($_GET['term']));
     $composite_id = $_GET['composite_id'];
     $component_id = $_GET['component_id'];
     if (empty($term) || empty($composite_id) || empty($component_id)) {
         die;
     }
     $composite_data = get_post_meta($composite_id, '_bto_data', true);
     $component_data = isset($composite_data[$component_id]) ? $composite_data[$component_id] : false;
     if (false == $composite_data || false == $component_data) {
         die;
     }
     // Run query to get component option ids
     $component_options = $woocommerce_composite_products->api->get_component_options($component_data);
     // Add variation ids to component option ids
     if ($x == 'search_component_options_in_scenario') {
         $variations_args = array('post_type' => array('product_variation'), 'post_status' => 'publish', 'posts_per_page' => -1, 'post_parent' => array_merge(array('0'), $component_options), 'fields' => 'ids');
         $component_options_variations = get_posts($variations_args);
         $component_options = array_merge($component_options, $component_options_variations);
     }
     if (is_numeric($term)) {
         $args = array('post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'post__in' => array(0, $term), 'fields' => 'ids');
         $args2 = array('post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => array(array('key' => '_sku', 'value' => $term, 'compare' => 'LIKE')), 'fields' => 'ids');
         $args3 = array('post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'post_parent' => $term, 'fields' => 'ids');
         $posts = array_unique(array_intersect($component_options, array_merge(get_posts($args), get_posts($args2), get_posts($args3))));
     } else {
         $args = array('post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 's' => $term, 'fields' => 'ids');
         $args2 = array('post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => array(array('key' => '_sku', 'value' => $term, 'compare' => 'LIKE')), 'fields' => 'ids');
         $posts = array_unique(array_intersect($component_options, array_merge(get_posts($args), get_posts($args2))));
     }
     $found_products = array();
     $loop = 0;
     if ($posts) {
         foreach ($posts as $post) {
             if ($loop > 1000) {
                 continue;
             }
             $product = WC_CP_Core_Compatibility::wc_get_product($post);
             if ($product->product_type === 'variation') {
                 $found_products[$post] = $woocommerce_composite_products->api->get_product_variation_title($product);
             } else {
                 if ($x == 'search_component_options_in_scenario' && $product->product_type === 'variable') {
                     $found_products[$post] = $woocommerce_composite_products->api->get_product_title($product) . ' ' . __('— All Variations', 'woocommerce-composite-products');
                 } else {
                     $found_products[$post] = $woocommerce_composite_products->api->get_product_title($product);
                 }
             }
             $loop++;
         }
     }
     wp_send_json($found_products);
 }
 /**
  * Validate that all managed items in the collection are in stock.
  *
  * @param  int    $composite_id
  * @return boolean
  */
 public function validate_stock($composite_id)
 {
     $managed_items = $this->get_managed_items();
     if (empty($managed_items)) {
         return true;
     }
     // Stock Validation
     foreach ($managed_items as $managed_item_id => $managed_item) {
         $quantity = $managed_item['quantity'];
         // Get the product
         $product_data = WC_CP_Core_Compatibility::wc_get_product($managed_item_id);
         if (!$product_data) {
             return false;
         }
         // is_sold_individually
         if ($product_data->sold_individually === 'yes' && $quantity > 1) {
             wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — only 1 "%2$s" may be purchased.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title()), 'error');
             return false;
         }
         // Check product is_purchasable
         if (!$product_data->is_purchasable()) {
             wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — "%2$s" cannot be purchased.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title()), 'error');
             return false;
         }
         // Stock check - only check if we're managing stock and backorders are not allowed
         if (!$product_data->is_in_stock()) {
             if ($product_data->product_type === 'variable') {
                 wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — your "%2$s" selection is out of stock.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title()), 'error');
             } else {
                 wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — "%2$s" is out of stock.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title()), 'error');
             }
             return false;
         } elseif (!$product_data->has_enough_stock($quantity)) {
             if ($product_data->product_type === 'variable') {
                 wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — your "%2$s" selection does not have enough stock (%3$s remaining).', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title(), $product_data->get_stock_quantity()), 'error');
             } else {
                 wc_add_notice(sprintf(__('This "%1$s" configuration cannot be added to the cart — there is not enough stock of "%2$s" (%3$s remaining).', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title(), $product_data->get_stock_quantity()), 'error');
             }
             return false;
         }
         // Stock check - this time accounting for whats already in-cart
         $product_qty_in_cart = WC()->cart->get_cart_item_quantities();
         if ($product_data->managing_stock()) {
             // Variations
             if ($managed_item['is_variation'] && $product_data->variation_has_stock) {
                 if (isset($product_qty_in_cart[$managed_item_id]) && !$product_data->has_enough_stock($product_qty_in_cart[$managed_item_id] + $quantity)) {
                     wc_add_notice(sprintf('<a href="%s" class="button wc-forward">%s</a> %s', WC()->cart->get_cart_url(), __('View Cart', 'woocommerce'), sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart because there is not enough stock of &quot;%2$s&quot; &mdash; we have %3$s in stock and you already have %4$s in your cart.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title(), $product_data->get_stock_quantity(), $product_qty_in_cart[$managed_item_id])), 'error');
                     return false;
                 }
                 // Products
             } else {
                 if (isset($product_qty_in_cart[$managed_item_id]) && !$product_data->has_enough_stock($product_qty_in_cart[$managed_item_id] + $quantity)) {
                     wc_add_notice(sprintf('<a href="%s" class="button wc-forward">%s</a> %s', WC()->cart->get_cart_url(), __('View Cart', 'woocommerce'), sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart because there is not enough stock of &quot;%2$s&quot; &mdash; we have %3$s in stock and you already have %4$s in your cart.', 'woocommerce-composite-products'), get_the_title($composite_id), $product_data->get_title(), $product_data->get_stock_quantity(), $product_qty_in_cart[$managed_item_id])), 'error');
                     return false;
                 }
             }
         }
     }
     return true;
 }
 /**
  * Inserts bundle contents after main wishlist bundle item is displayed.
  *
  * @param  array    $item       Wishlist item
  * @param  array    $wishlist   Wishlist
  * @return void
  */
 public function wishlist_after_list_item_name($item, $wishlist)
 {
     global $woocommerce_composite_products;
     if (!empty($item['composite_data'])) {
         echo '<dl>';
         foreach ($item['composite_data'] as $composited_item => $composited_item_data) {
             echo '<dt class="component_title_meta wishlist_component_title_meta">' . $composited_item_data['title'] . ':</dt>';
             echo '<dd class="component_option_meta wishlist_component_option_meta">' . get_the_title($composited_item_data['product_id']) . ' <strong class="component_quantity_meta wishlist_component_quantity_meta product-quantity">&times; ' . $composited_item_data['quantity'] . '</strong></dd>';
             if (!empty($composited_item_data['attributes'])) {
                 $attributes = '';
                 foreach ($composited_item_data['attributes'] as $attribute_name => $attribute_value) {
                     $taxonomy = wc_attribute_taxonomy_name(str_replace('attribute_pa_', '', urldecode($attribute_name)));
                     // If this is a term slug, get the term's nice name
                     if (taxonomy_exists($taxonomy)) {
                         $term = get_term_by('slug', $attribute_value, $taxonomy);
                         if (!is_wp_error($term) && $term && $term->name) {
                             $attribute_value = $term->name;
                         }
                         $label = wc_attribute_label($taxonomy);
                         // If this is a custom option slug, get the options name
                     } else {
                         $attribute_value = apply_filters('woocommerce_variation_option_name', $attribute_value);
                         $composited_product = WC_CP_Core_Compatibility::wc_get_product($composited_item_data['product_id']);
                         $product_attributes = $composited_product->get_attributes();
                         if (isset($product_attributes[str_replace('attribute_', '', $attribute_name)])) {
                             $label = wc_attribute_label($product_attributes[str_replace('attribute_', '', $attribute_name)]['name']);
                         } else {
                             $label = $attribute_name;
                         }
                     }
                     $attributes = $attributes . $label . ': ' . $attribute_value . ', ';
                 }
                 echo '<dd class="component_attribute_meta wishlist_component_attribute_meta">' . rtrim($attributes, ', ') . '</dd>';
             }
         }
         echo '</dl>';
         echo '<p class="component_notice wishlist_component_notice">' . __('*', 'woocommerce-composite-products') . '&nbsp;&nbsp;<em>' . __('Accurate pricing info available in cart.', 'woocommerce-composite-products') . '</em></p>';
     }
 }