/** * Process the product variable meta * * @param int $parent_id Product ID * @return void */ public function save($parent_id) { global $wpdb; // Do not run if there are no variations if (!isset($_POST['variations'])) { return; } // Get the attributes to be used later $attributes = (array) maybe_unserialize(get_post_meta($parent_id, 'product_attributes', true)); $minimal_price = PHP_INT_MAX; foreach ($_POST['variations'] as $ID => $meta) { /** * Generate a post title of the current variation. * Parent Title - [attribute: variation] */ $taxes = array(); foreach ($meta as $k => $v) { if (strstr($k, 'tax_')) { $tax = substr($k, 4); $taxes[] = sprintf('[%s: %s]', $tax, !empty($v) ? $v : 'Any ' . $tax); } } $post_title = !empty($_POST['post_title']) ? $_POST['post_title'] : the_title('', '', false); $title = sprintf('%s - %s', $post_title, implode($taxes, ' ')); /** * Prevent duplicate variations */ // Update post data or Add post if new if (strpos($ID, '_new')) { // check for an existing variation with matching attributes to prevent duplication $current_meta = $meta; foreach ($current_meta as $current_id => $current_value) { // discard everything but the taxonomies if (strpos($current_id, 'tax_') !== 0) { unset($current_meta[$current_id]); } } // we now have just the taxonomies in use for this new variation in $current_meta, match them up to others $all_variations = $_POST['variations']; unset($all_variations[$ID]); // we don't need the current new variation $duplicate = false; foreach ($all_variations as $this_id => $this_meta) { $haystack_meta = $this_meta; foreach ($haystack_meta as $haystack_id => $haystack_value) { // discard everything but the taxonomies if (strpos($haystack_id, 'tax_') !== 0) { unset($haystack_meta[$haystack_id]); } } // we now have the taxonomies only for this haystack variation $result = array_diff($haystack_meta, $current_meta); if (empty($result)) { $duplicate = true; } } if (!$duplicate) { $ID = wp_insert_post(array('post_title' => !empty($title) ? $title : "#{$parent_id}: Child Variation", 'post_status' => isset($meta['enabled']) ? 'publish' : 'draft', 'post_parent' => $parent_id, 'post_type' => 'product_variation')); } else { // silent fail, should put up a message? } } else { $_product = new jigoshop_product_variation($ID); if (Jigoshop_Base::get_options()->get('jigoshop_hide_no_stock_product') == 'yes' && $_product->managing_stock()) { if ($meta['stock'] <= Jigoshop_Base::get_options()->get('jigoshop_notify_no_stock_amount') && $meta['stock'] != '') { unset($meta['enabled']); } else { $meta['enabled'] = true; } } $wpdb->update($wpdb->posts, array('post_title' => !empty($title) ? $title : "#{$parent_id}: Child Variation", 'post_status' => isset($meta['enabled']) ? 'publish' : 'draft'), array('ID' => $ID)); } // Set the product type wp_set_object_terms($ID, sanitize_title($meta['product-type']), 'product_type'); // Set variation meta data $meta['regular_price'] = jigoshop_sanitize_num($meta['regular_price']); if (!empty($meta['regular_price']) && !is_numeric($meta['regular_price'])) { add_filter('redirect_post_location', function ($location) { return add_query_arg('jigoshop_message', 'invalid_variation_price', $location); }); $meta['regular_price'] = 0.0; } if (empty($meta['regular_price'])) { $meta['regular_price'] = null; } update_post_meta($ID, 'sku', $meta['sku']); update_post_meta($ID, 'regular_price', $meta['regular_price']); if ($meta['regular_price'] < $minimal_price) { $minimal_price = $meta['regular_price']; } $sale_price = !empty($meta['sale_price']) ? !strstr($meta['sale_price'], '%') ? jigoshop_sanitize_num($meta['sale_price']) : $meta['sale_price'] : ''; if (strstr($meta['sale_price'], '%')) { update_post_meta($ID, 'sale_price', $sale_price); } else { if (!empty($sale_price) && $sale_price < jigoshop_sanitize_num($meta['regular_price'])) { update_post_meta($ID, 'sale_price', $sale_price); } else { // silently fail if entered sale price > regular price (or nothing entered) update_post_meta($ID, 'sale_price', ''); } } update_post_meta($ID, 'weight', $meta['weight']); update_post_meta($ID, 'length', $meta['length']); update_post_meta($ID, 'height', $meta['height']); update_post_meta($ID, 'width', $meta['width']); update_post_meta($ID, 'stock', $meta['stock']); update_post_meta($ID, '_thumbnail_id', $meta['_thumbnail_id']); // Downloadable Only if ($meta['product-type'] == 'downloadable') { update_post_meta($ID, 'file_path', $meta['file_path']); update_post_meta($ID, 'download_limit', $meta['download_limit']); } // Remove the current data delete_post_meta($ID, 'variation_data'); // Update taxonomies $variation_data = array(); foreach ($attributes as $attribute) { // Skip if attribute is not for variation if (!isset($attribute['variation'])) { continue; } // Configure the data $key = 'tax_' . sanitize_title($attribute['name']); if (isset($meta[$key])) { $variation_data[$key] = $meta[$key]; } } update_post_meta($ID, 'variation_data', $variation_data); do_action('jigoshop_variable_product_table_data_save', $ID, $meta); } // Update default attribute options setting $default_attributes = array(); foreach ($attributes as $attribute) { if (isset($attribute['variation'])) { $value = 'default_attribute_' . sanitize_title($attribute['name']); if (isset($_POST[$value])) { $value = esc_attr(trim($_POST[$value])); } else { $value = null; } if ($value) { $default_attributes[sanitize_title($attribute['name'])] = $value; } } } update_post_meta($parent_id, '_default_attributes', $default_attributes); update_post_meta($parent_id, 'regular_price', $minimal_price); }
function jigoshop_add_order_item() { $jigoshop_options = Jigoshop_Base::get_options(); check_ajax_referer('add-order-item', 'security'); global $wpdb; $item_to_add = trim(stripslashes($_POST['item_to_add'])); $post = ''; // Find the item if (is_numeric($item_to_add)) { $post = get_post($item_to_add); } if (!$post || $post->post_type !== 'product' && $post->post_type !== 'product_variation') { $post_id = $wpdb->get_var($wpdb->prepare("\n\t\t\tSELECT post_id\n\t\t\tFROM {$wpdb->posts}\n\t\t\tLEFT JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)\n\t\t\tWHERE {$wpdb->postmeta}.meta_key = 'SKU'\n\t\t\tAND {$wpdb->posts}.post_status = 'publish'\n\t\t\tAND {$wpdb->posts}.post_type = 'shop_product'\n\t\t\tAND {$wpdb->postmeta}.meta_value = %s\n\t\t\tLIMIT 1\n\t\t", $item_to_add)); $post = get_post($post_id); } if (!$post || $post->post_type !== 'product' && $post->post_type !== 'product_variation') { die; } if ($post->post_type == "product") { $_product = new jigoshop_product($post->ID); } else { $_product = new jigoshop_product_variation($post->ID); } $loop = 0; ?> <tr class="item"> <?php do_action('jigoshop_admin_order_item_before_prod_id', intval($_POST['item_no'])); ?> <td class="product-id">#<?php echo $_product->id; ?> </td> <td class="variation-id"><?php if (isset($_product->variation_id)) { echo $_product->variation_id; } else { echo '-'; } ?> </td> <td class="product-sku"><?php if ($_product->sku) { echo $_product->sku; } ?> </td> <td class="name"><a href="<?php echo esc_url(admin_url('post.php?post=' . $_product->id . '&action=edit')); ?> "><?php echo $_product->get_title(); ?> </a></td> <td class="variation"><?php if (isset($_product->variation_data)) { echo jigoshop_get_formatted_variation($_product, array(), true); } else { echo '-'; } ?> </td> <!--<td> <table class="meta" cellspacing="0"> <tfoot> <tr> <td colspan="3"><button class="add_meta button"><?php _e('Add meta', 'jigoshop'); ?> </button></td> </tr> </tfoot> <tbody></tbody> </table> </td>--> <?php do_action('jigoshop_admin_order_item_values', $_product, array(), 0); ?> <td class="quantity"><input type="text" name="item_quantity[]" placeholder="<?php _e('Quantity e.g. 2', 'jigoshop'); ?> " value="1" /></td> <td class="cost"><input type="text" name="item_cost[]" placeholder="<?php _e('Cost per unit ex. tax e.g. 2.99', 'jigoshop'); ?> " value="<?php echo esc_attr($jigoshop_options->get('jigoshop_prices_include_tax') == 'yes' ? $_product->get_price_excluding_tax() : $_product->get_price()); ?> " /></td> <td class="tax"><input type="text" name="item_tax_rate[]" placeholder="<?php _e('Tax Rate e.g. 20.0000', 'jigoshop'); ?> " value="<?php echo esc_attr(jigoshop_tax::calculate_total_tax_rate($_product->get_tax_base_rate())); ?> " /></td> <td class="center"> <input type="hidden" name="item_id[]" value="<?php echo esc_attr($_product->id); ?> " /> <input type="hidden" name="item_name[]" value="<?php echo esc_attr($_product->get_title()); ?> " /> <input type="hidden" name="item_variation_id[]" value="<?php if ($_product instanceof jigoshop_product_variation) { echo esc_attr($_product->variation_id); } else { echo ''; } ?> " /> <button type="button" class="remove_row button">×</button> </td> </tr> <?php // Quit out die; }
/** * Order attributes meta box * * Displays a list of all attributes which were selected in the order */ function jigoshop_order_attributes_meta_box($post) { $order = new jigoshop_order($post->ID); ?> <ul class="order-attributes"><?php foreach ($order->items as $item_id => $item) { ?> <li> <?php do_action('jigoshop_order_attributes_meta_box_before_item', $item, $item_id); ?> <b> <?php do_action('jigoshop_order_attributes_meta_box_before_item_title', $item_id); ?> <?php echo esc_html(isset($item['name']) ? $item['name'] : ''); ?> </b> <?php $taxonomies_count = 0; // process only variations if (isset($item['variation_id']) && !empty($item['variation_id'])) { foreach (jigoshop_product::getAttributeTaxonomies() as $attr_tax) { $identifier = 'tax_' . $attr_tax->attribute_name; if (!isset($item['variation'][$identifier])) { continue; } $product = new jigoshop_product_variation($item['variation_id']); $attr_label = str_replace('tax_', '', $identifier); $attr_label = $product->attribute_label('pa_' . $attr_label); $terms = get_terms('pa_' . $attr_tax->attribute_name, array('orderby' => 'slug', 'hide_empty' => false)); ?> <div class="order-item-attribute" style="display:block"> <span style="display:block"><?php echo esc_html($attr_label); ?> </span> <select name="order_attributes[<?php echo $item_id; ?> ][<?php echo $identifier; ?> ]"> <?php foreach ($terms as $term) { ?> <option <?php selected($item['variation'][$identifier], $term->slug); ?> value="<?php echo esc_attr($term->slug); ?> "> <?php echo esc_html($term->name); ?> </option> <?php } ?> </select> </div> <?php $taxonomies_count++; } } if ($taxonomies_count === 0) { ?> <div class="order-item-attribute no-items-in-order" style="display:block"> <?php _e('No attributes for this item.', 'jigoshop'); ?> </div><?php } do_action('jigoshop_order_attributes_meta_box_after_item', $item, $item_id); ?> </li><?php } ?> </ul> <script type="text/javascript"> /*<![CDATA[*/ jQuery(function() { jQuery(".order-item-attribute select").select2({ width: '255px' }); }); /*]]>*/ </script> <?php }
/** * Add a product to the cart * * @param string $product_id contains the id of the product to add to the cart * @param int|string $quantity contains the quantity of the item to add * @param int|string $variation_id * @param array $variation attribute values * @return bool */ public static function add_to_cart($product_id, $quantity = 1, $variation_id = '', $variation = array()) { if ($quantity < 0) { $quantity = 0; } // Load cart item data - may be added by other plugins $cart_item_data = (array) apply_filters('jigoshop_add_cart_item_data', array(), $product_id); $cart_id = self::generate_cart_id($product_id, $variation_id, $variation, $cart_item_data); $cart_item_key = self::find_product_in_cart($cart_id); // prevents adding non-valid products to the cart $this_post = get_post($product_id); if ($this_post->post_type != 'product') { jigoshop::add_error(__('You cannot add this item to your Cart as it does not appear to be a valid Product.', 'jigoshop')); return false; } // create a product record to work from if (empty($variation_id)) { $product = new jigoshop_product($product_id); } else { $product = new jigoshop_product_variation($variation_id); } // product with a given ID doesn't exists if (empty($product)) { return false; } // prevents adding products with no price to the cart if ($product->get_price() === '') { jigoshop::add_error(__('You cannot add this product to your cart because its price is not yet announced', 'jigoshop')); return false; } // products newly added to the Cart will not have a $cart_item_key, use 0 quantity $in_cart_qty = !empty($cart_item_key) ? self::$cart_contents[$cart_item_key]['quantity'] : 0; // prevents adding products to the cart without enough quantity on hand if (!$product->has_enough_stock($quantity + $in_cart_qty)) { jigoshop::add_error(sprintf(__('We are sorry. We do not have enough "%s" to fill your request.', 'jigoshop'), $product->get_title())); if (self::get_options()->get('jigoshop_show_stock') == 'yes') { if ($in_cart_qty > 0) { jigoshop::add_error(sprintf(__('You have %d of them in your Cart and we have %d available at this time.', 'jigoshop'), $in_cart_qty, $product->get_stock())); } else { jigoshop::add_error(sprintf(__('There are only %d left in stock.', 'jigoshop'), $product->get_stock())); } } return false; } // if product is already in the cart change its quantity if ($cart_item_key) { $quantity = (int) $quantity + self::$cart_contents[$cart_item_key]['quantity']; self::set_quantity($cart_item_key, apply_filters('jigoshop_cart_item_quantity', $quantity, $product, $cart_item_key)); } else { // otherwise add new item to the cart self::$cart_contents[$cart_id] = apply_filters('jigoshop_add_cart_item', array('data' => $product, 'product_id' => $product_id, 'variation' => $variation, 'variation_id' => $variation_id, 'quantity' => (int) $quantity, 'unit_price' => 0, 'tax' => 0, 'discount' => 0, 'price_includes_tax' => self::get_options()->get('jigoshop_prices_include_tax')), $cart_item_data); } self::set_session(); return true; }
</td> </tr> <?php } ?> </tfoot> <tbody> <?php if (sizeof($order->items) > 0) { ?> <?php foreach ($order->items as $item) { ?> <?php if (isset($item['variation_id']) && $item['variation_id'] > 0) { $product = new jigoshop_product_variation($item['variation_id']); if (is_array($item['variation'])) { $product->set_variation_attributes($item['variation']); } } else { $product = new jigoshop_product($item['id']); } ?> <tr> <td><?php echo $product->get_sku(); ?> </td> <td class="product-name"> <?php echo $item['name'];