Example #1
0
function fflcommerce_process_shop_order_meta($post_id)
{
    $fflcommerce_options = FFLCommerce_Base::get_options();
    $fflcommerce_errors = array();
    $order = new fflcommerce_order($post_id);
    // Get old data + attributes
    $data = (array) maybe_unserialize(get_post_meta($post_id, 'order_data', true));
    //Get old order items
    $old_order_items = (array) maybe_unserialize(get_post_meta($post_id, 'order_items', true));
    // Add/Replace data to array
    $customerDetails = array('billing_first_name', 'billing_last_name', 'billing_company', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_postcode', 'billing_country', 'billing_state', 'billing_email', 'billing_phone', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_postcode', 'shipping_country', 'shipping_state');
    $order_fields = array('shipping_method', 'shipping_service', 'payment_method', 'order_subtotal', 'order_discount_subtotal', 'order_shipping', 'order_discount', 'order_discount_coupons', 'order_tax_total', 'order_shipping_tax', 'order_total', 'order_total_prices_per_tax_class_ex_tax');
    /* Pre-fill the customer addresses */
    foreach ($customerDetails as $key) {
        $order_fields[] = $key;
        /* Checks if this is a new order from "Add Order" button */
        if (!empty($_POST['auto_draft']) && !empty($_POST['customer_user']) && empty($_POST[$key])) {
            $data[$key] = get_user_meta($_POST['customer_user'], $key, true);
        }
    }
    //run stripslashes on all valid fields
    foreach ($order_fields as $field_name) {
        if (isset($_POST[$field_name])) {
            $data[$field_name] = stripslashes($_POST[$field_name]);
        }
    }
    // Sanitize numeric values
    $data['order_total'] = fflcommerce_sanitize_num($data['order_total']);
    $data['order_subtotal'] = fflcommerce_sanitize_num($data['order_subtotal']);
    // if a shipping or payment methods has changed, update the method title for pretty display
    if (isset($_POST['shipping_method'])) {
        $data['shipping_service'] = '';
        $shipping_methods = fflcommerce_shipping::get_all_methods();
        if (!empty($shipping_methods)) {
            foreach ($shipping_methods as $method) {
                if ($_POST['shipping_method'] == $method->id) {
                    $data['shipping_service'] = $method->title;
                }
            }
        }
    }
    if (isset($_POST['payment_method'])) {
        $data['payment_method_title'] = '';
        $payment_methods = fflcommerce_payment_gateways::get_available_payment_gateways();
        if (!empty($payment_methods)) {
            foreach ($payment_methods as $method) {
                if ($_POST['payment_method'] == $method->id) {
                    $data['payment_method_title'] = $method->title;
                }
            }
        }
    }
    // if total tax has been modified from order tax, then create a customized tax array
    // just for the order. At this point, we no longer know about multiple tax classes.
    // Even if we used the old tax array data, we still don't know how to break down
    // the amounts since they're customized.
    if (isset($data['order_tax_total']) && $order->get_total_tax() != $data['order_tax_total']) {
        $new_tax = $data['order_tax_total'];
        $data['order_tax'] = fflcommerce_tax::create_custom_tax($data['order_total'] - $data['order_tax_total'], $data['order_tax_total'], $data['order_shipping_tax'], isset($data['order_tax_divisor']) ? $data['order_tax_divisor'] : null);
    }
    // Customer
    update_post_meta($post_id, 'customer_user', (int) $_POST['customer_user']);
    // Order items
    $order_items = array();
    if (isset($_POST['item_id'])) {
        $item_id = $_POST['item_id'];
        $item_variation = $_POST['item_variation_id'];
        $item_name = $_POST['item_name'];
        $item_quantity = $_POST['item_quantity'];
        $item_cost = $_POST['item_cost'];
        $item_tax_rate = $_POST['item_tax_rate'];
        for ($i = 0; $i < count($item_id); $i++) {
            if (!isset($item_id[$i]) || !isset($item_name[$i]) || !isset($item_quantity[$i]) || !isset($item_cost[$i]) || !isset($item_tax_rate[$i])) {
                continue;
            }
            $variation_id = '';
            $variation = '';
            if (!empty($item_variation[$i])) {
                $variation_id = (int) $item_variation[$i];
                // if this is a variation, we should check if it is an old one
                // and copy the 'variation' field describing details of variation
                foreach ($old_order_items as $old_item_index => $old_item) {
                    if ($old_item['variation_id'] == $variation_id) {
                        $variation = $old_item['variation'];
                        unset($old_order_items[$old_item_index]);
                        break;
                    }
                }
                // override variation with values from $_POST
                if (isset($_POST['order_attributes'][$i]) && is_array($_POST['order_attributes'][$i])) {
                    foreach ($_POST['order_attributes'][$i] as $var_key => $var_value) {
                        $variation[$var_key] = $var_value;
                    }
                }
            }
            $cost_inc_tax = $fflcommerce_options->get('fflcommerce_prices_include_tax') == 'yes' ? number_format((double) fflcommerce_clean($item_cost[$i]), 2, '.', '') : -1;
            $order_items[] = apply_filters('update_order_item', array('id' => htmlspecialchars(stripslashes($item_id[$i])), 'variation_id' => $variation_id, 'variation' => $variation, 'name' => htmlspecialchars(stripslashes($item_name[$i])), 'qty' => (int) $item_quantity[$i], 'cost' => number_format((double) fflcommerce_clean($item_cost[$i]), 2, '.', ''), 'cost_inc_tax' => $cost_inc_tax, 'taxrate' => number_format((double) fflcommerce_clean($item_tax_rate[$i]), 4, '.', '')));
        }
    }
    // Save
    update_post_meta($post_id, 'order_data', $data);
    update_post_meta($post_id, 'order_items', $order_items);
    // Order status
    $order->update_status($_POST['order_status']);
    // Handle button actions
    if (isset($_POST['reduce_stock']) && $_POST['reduce_stock'] && count($order_items) > 0) {
        $order->add_order_note(__('Manually reducing stock.', 'fflcommerce'));
        foreach ($order_items as $order_item) {
            $_product = $order->get_product_from_item($order_item);
            if ($_product->exists) {
                if ($_product->managing_stock()) {
                    $old_stock = $_product->stock;
                    $new_quantity = $_product->reduce_stock($order_item['qty']);
                    $order->add_order_note(sprintf(__('Item #%s stock reduced from %s to %s.', 'fflcommerce'), $order_item['id'], $old_stock, $new_quantity));
                    if ($new_quantity < 0) {
                        if ($old_stock < 0) {
                            $backorder_qty = $order_item['qty'];
                        } else {
                            $backorder_qty = $old_stock - $order_item['qty'];
                        }
                        do_action('fflcommerce_product_on_backorder_notification', $post_id, $_product, $backorder_qty);
                    }
                    // stock status notifications
                    if ($fflcommerce_options->get('fflcommerce_notify_no_stock') == 'yes' && $fflcommerce_options->get('fflcommerce_notify_no_stock_amount') >= 0 && $fflcommerce_options->get('fflcommerce_notify_no_stock_amount') >= $new_quantity) {
                        do_action('fflcommerce_no_stock_notification', $_product);
                    } else {
                        if ($fflcommerce_options->get('fflcommerce_notify_low_stock') == 'yes' && $fflcommerce_options->get('fflcommerce_notify_low_stock_amount') >= $new_quantity) {
                            do_action('fflcommerce_low_stock_notification', $_product);
                        }
                    }
                }
            } else {
                $order->add_order_note(sprintf(__('Item %s %s not found, skipping.', 'fflcommerce'), $order_item['id'], $order_item['name']));
            }
        }
        $order->add_order_note(__('Manual stock reduction complete.', 'fflcommerce'));
    } else {
        if (isset($_POST['restore_stock']) && $_POST['restore_stock'] && sizeof($order_items) > 0) {
            $order->add_order_note(__('Manually restoring stock.', 'fflcommerce'));
            foreach ($order_items as $order_item) {
                $_product = $order->get_product_from_item($order_item);
                if ($_product->exists) {
                    if ($_product->managing_stock()) {
                        $old_stock = $_product->stock;
                        $new_quantity = $_product->increase_stock($order_item['qty']);
                        $order->add_order_note(sprintf(__('Item #%s stock increased from %s to %s.', 'fflcommerce'), $order_item['id'], $old_stock, $new_quantity));
                    }
                } else {
                    $order->add_order_note(sprintf(__('Item %s %s not found, skipping.', 'fflcommerce'), $order_item['id'], $order_item['name']));
                }
            }
            $order->add_order_note(__('Manual stock restore complete.', 'fflcommerce'));
        } else {
            if (isset($_POST['invoice']) && $_POST['invoice']) {
                // Mail link to customer
                fflcommerce_send_customer_invoice($order->id);
            }
        }
    }
    // Error Handling
    if (count($fflcommerce_errors) > 0) {
        $fflcommerce_options->set('fflcommerce_errors', $fflcommerce_errors);
    }
}
Example #2
0
 /**
  * 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 fflcommerce_product_variation($ID);
             if (FFLCommerce_Base::get_options()->get('fflcommerce_hide_no_stock_product') == 'yes' && $_product->managing_stock()) {
                 if ($meta['stock'] <= fflcommerce_Base::get_options()->get('fflcommerce_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'] = fflcommerce_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('fflcommerce_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'], '%') ? fflcommerce_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 < fflcommerce_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('fflcommerce_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 fflcommerce_save_bulk_edit()
{
    check_ajax_referer('update-product-stock-price', 'security');
    $post_ids = isset($_POST['post_ids']) && !empty($_POST['post_ids']) ? $_POST['post_ids'] : array();
    $stock = isset($_POST['stock']) ? $_POST['stock'] : NULL;
    $price = isset($_POST['price']) ? $_POST['price'] : NULL;
    if (!empty($post_ids) && is_array($post_ids)) {
        foreach ($post_ids as $post_id) {
            $_product = new fflcommerce_product($post_id);
            if (trim($stock) !== '' && $_product->managing_stock()) {
                $stock = empty($stock) ? 0 : fflcommerce_sanitize_num($stock);
                // TODO: do we need to check to hide products at low stock threshold? (-JAP-)
                update_post_meta($post_id, 'stock', $stock);
            }
            if (trim($price) !== '' && !$_product->is_type(array('grouped'))) {
                update_post_meta($post_id, 'regular_price', fflcommerce_sanitize_num($price));
            }
        }
    }
    die;
}
function fflcommerce_category_thumbnail_field_save($term_id, $tt_id, $taxonomy)
{
    if ($taxonomy !== 'product_cat') {
        return;
    }
    if (isset($_POST['product_cat_thumbnail_id'])) {
        update_metadata('fflcommerce_term', $term_id, 'thumbnail_id', $_POST['product_cat_thumbnail_id']);
    }
    foreach (apply_filters('fflcommerce_optional_product_category_fields', array()) as $field) {
        if (isset($_POST['product_cat_' . $field['id']])) {
            $value = $_POST['product_cat_' . $field['id']];
            update_metadata('fflcommerce_term', $term_id, $field['id'], $field['type'] === 'number' ? fflcommerce_sanitize_num($value) : $value);
        }
    }
}
 public function save($post_id)
 {
     // Set the product type
     wp_set_object_terms($post_id, sanitize_title($_POST['product-type']), 'product_type');
     // Process general product data
     $regular_price = 0.0;
     if (isset($_POST['regular_price'])) {
         if ($_POST['regular_price'] != '') {
             $regular_price = fflcommerce_sanitize_num($_POST['regular_price']);
         } else {
             $regular_price = '';
         }
     }
     update_post_meta($post_id, 'regular_price', $regular_price);
     $sale_price = !empty($_POST['sale_price']) ? !strstr($_POST['sale_price'], '%') ? fflcommerce_sanitize_num($_POST['sale_price']) : $_POST['sale_price'] : '';
     if (strstr($_POST['sale_price'], '%')) {
         update_post_meta($post_id, 'sale_price', $sale_price);
     } else {
         if (!empty($sale_price) && $sale_price < $regular_price) {
             update_post_meta($post_id, 'sale_price', $sale_price);
         } else {
             // silently fail if entered sale price > regular price (or nothing entered)
             update_post_meta($post_id, 'sale_price', '');
         }
     }
     // finally, if this product is a 'variable' or 'grouped', then there should never be a sale_price here
     // perhaps it was a 'simple' product once and was changed (see rhr #437)
     $terms = wp_get_object_terms($post_id, 'product_type');
     if (!empty($terms)) {
         if (!is_wp_error($terms)) {
             if (sizeof($terms) == 1) {
                 if (in_array($terms[0]->slug, array('variable', 'grouped'))) {
                     delete_post_meta($post_id, 'sale_price');
                 }
             }
         }
     }
     if (isset($_POST['weight'])) {
         update_post_meta($post_id, 'weight', (double) $_POST['weight']);
     }
     if (isset($_POST['length'])) {
         update_post_meta($post_id, 'length', (double) $_POST['length']);
     }
     if (isset($_POST['width'])) {
         update_post_meta($post_id, 'width', (double) $_POST['width']);
     }
     if (isset($_POST['height'])) {
         update_post_meta($post_id, 'height', (double) $_POST['height']);
     }
     update_post_meta($post_id, 'tax_status', $_POST['tax_status']);
     update_post_meta($post_id, 'tax_classes', isset($_POST['tax_classes']) ? $_POST['tax_classes'] : array());
     update_post_meta($post_id, 'visibility', $_POST['product_visibility']);
     update_post_meta($post_id, 'featured', isset($_POST['featured']));
     update_post_meta($post_id, 'customizable', $_POST['product_customize']);
     update_post_meta($post_id, 'customized_length', $_POST['customized_length']);
     // Downloadable Only
     if ($_POST['product-type'] == 'downloadable') {
         update_post_meta($post_id, 'file_path', $_POST['file_path']);
         update_post_meta($post_id, 'download_limit', $_POST['download_limit']);
     }
     // Process the SKU
     if (FFLCommerce_Base::get_options()->get('fflcommerce_enable_sku') !== 'no') {
         $this->is_unique_sku($post_id, $_POST['sku']) ? update_post_meta($post_id, 'sku', $_POST['sku']) : delete_post_meta($post_id, 'sku');
     }
     // Process the Brand
     if (FFLCommerce_Base::get_options()->get('fflcommerce_enable_brand') !== 'no') {
         $this->is_unique_sku($post_id, $_POST['brand']) ? update_post_meta($post_id, 'brand', $_POST['brand']) : delete_post_meta($post_id, 'brand');
     }
     // Process the GTIN
     if (FFLCommerce_Base::get_options()->get('fflcommerce_enable_gtin') !== 'no') {
         $this->is_unique_sku($post_id, $_POST['gtin']) ? update_post_meta($post_id, 'gtin', $_POST['gtin']) : delete_post_meta($post_id, 'gtin');
     }
     // Process the MPN
     if (FFLCommerce_Base::get_options()->get('fflcommerce_enable_mpn') !== 'no') {
         $this->is_unique_sku($post_id, $_POST['mpn']) ? update_post_meta($post_id, 'mpn', $_POST['mpn']) : delete_post_meta($post_id, 'mpn');
     }
     // Process the attributes
     update_post_meta($post_id, 'product_attributes', $this->process_attributes($_POST, $post_id));
     // Process the stock information
     $stockresult = $this->process_stock($_POST);
     if (is_array($stockresult)) {
         foreach ($stockresult as $key => $value) {
             update_post_meta($post_id, $key, $value);
         }
     }
     if ($_POST['product-type'] == 'external') {
         update_post_meta($post_id, 'external_url', $_POST['external_url']);
         update_post_meta($post_id, 'stock_status', 'instock');
         update_post_meta($post_id, 'manage_stock', false);
     }
     if ($_POST['product-type'] == 'variable') {
         update_post_meta($post_id, 'variation_order', $_POST['variation_order']);
     }
     // Process the sale dates
     foreach ($this->process_sale_dates($_POST, $post_id) as $key => $value) {
         update_post_meta($post_id, $key, $value);
     }
     // Do action for product type
     do_action('fflcommerce_process_product_meta_' . $_POST['product-type'], $post_id);
 }