2013-08-06 10:41:20 +00:00
< ? php
/**
2015-11-03 13:53:50 +00:00
* Product Data
2013-08-06 10:41:20 +00:00
*
* Displays the product data box , tabbed , with several panels covering price , stock etc .
*
2015-07-02 20:42:22 +00:00
* @ author WooThemes
* @ category Admin
* @ package WooCommerce / Admin / Meta Boxes
2016-10-26 17:02:50 +00:00
* @ version 2.7 . 0
2013-08-06 10:41:20 +00:00
*/
2014-06-27 13:08:39 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
2016-10-26 17:02:50 +00:00
exit ;
2014-06-27 13:08:39 +00:00
}
2013-08-06 10:41:20 +00:00
/**
2015-11-03 12:28:01 +00:00
* WC_Meta_Box_Product_Data Class .
2013-08-06 10:41:20 +00:00
*/
class WC_Meta_Box_Product_Data {
/**
2015-11-03 12:28:01 +00:00
* Output the metabox .
2016-01-04 21:31:36 +00:00
*
* @ param WP_Post $post
2013-08-06 10:41:20 +00:00
*/
public static function output ( $post ) {
2016-10-27 13:08:16 +00:00
global $post , $thepostid , $product_object ;
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
$thepostid = $post -> ID ;
2016-10-27 13:08:16 +00:00
$product_object = $thepostid ? wc_get_product ( $thepostid ) : new WC_Product ;
2013-08-06 10:41:20 +00:00
2016-10-27 13:08:16 +00:00
include ( 'views/html-product-data-panel.php' );
}
2014-08-31 07:18:21 +00:00
2016-10-27 13:08:16 +00:00
/**
* Show tab content / settings .
*/
private static function output_tabs () {
global $post , $thepostid , $product_object ;
include ( 'views/html-product-data-general.php' );
include ( 'views/html-product-data-inventory.php' );
include ( 'views/html-product-data-shipping.php' );
include ( 'views/html-product-data-linked-products.php' );
include ( 'views/html-product-data-attributes.php' );
include ( 'views/html-product-data-advanced.php' );
}
2013-08-06 10:41:20 +00:00
2016-10-27 13:08:16 +00:00
/**
* Return array of product type options .
* @ return array
*/
private static function get_product_type_options () {
return apply_filters ( 'product_type_options' , array (
2013-08-06 10:41:20 +00:00
'virtual' => array (
2013-08-17 00:55:05 +00:00
'id' => '_virtual' ,
2013-08-06 10:41:20 +00:00
'wrapper_class' => 'show_if_simple' ,
2013-08-17 00:55:05 +00:00
'label' => __ ( 'Virtual' , 'woocommerce' ),
'description' => __ ( 'Virtual products are intangible and aren\'t shipped.' , 'woocommerce' ),
2016-08-27 01:46:45 +00:00
'default' => 'no' ,
2013-08-06 10:41:20 +00:00
),
'downloadable' => array (
2013-08-17 00:55:05 +00:00
'id' => '_downloadable' ,
2013-08-06 10:41:20 +00:00
'wrapper_class' => 'show_if_simple' ,
2013-08-17 00:55:05 +00:00
'label' => __ ( 'Downloadable' , 'woocommerce' ),
'description' => __ ( 'Downloadable products give access to a file upon purchase.' , 'woocommerce' ),
2016-08-27 01:46:45 +00:00
'default' => 'no' ,
),
2013-08-06 10:41:20 +00:00
) );
2016-10-27 13:08:16 +00:00
}
2013-08-06 10:41:20 +00:00
2016-10-27 13:08:16 +00:00
/**
* Return array of tabs to show .
* @ return array
*/
private static function get_product_data_tabs () {
return apply_filters ( 'woocommerce_product_data_tabs' , array (
'general' => array (
'label' => __ ( 'General' , 'woocommerce' ),
'target' => 'general_product_data' ,
'class' => array ( 'hide_if_grouped' ),
),
'inventory' => array (
'label' => __ ( 'Inventory' , 'woocommerce' ),
'target' => 'inventory_product_data' ,
'class' => array ( 'show_if_simple' , 'show_if_variable' , 'show_if_grouped' , 'show_if_external' ),
),
'shipping' => array (
'label' => __ ( 'Shipping' , 'woocommerce' ),
'target' => 'shipping_product_data' ,
'class' => array ( 'hide_if_virtual' , 'hide_if_grouped' , 'hide_if_external' ),
),
'linked_product' => array (
'label' => __ ( 'Linked Products' , 'woocommerce' ),
'target' => 'linked_product_data' ,
'class' => array (),
),
'attribute' => array (
'label' => __ ( 'Attributes' , 'woocommerce' ),
'target' => 'product_attributes' ,
'class' => array (),
),
'variations' => array (
'label' => __ ( 'Variations' , 'woocommerce' ),
'target' => 'variable_product_options' ,
'class' => array ( 'variations_tab' , 'show_if_variable' ),
),
'advanced' => array (
'label' => __ ( 'Advanced' , 'woocommerce' ),
'target' => 'advanced_product_data' ,
'class' => array (),
),
) );
}
2013-08-06 10:41:20 +00:00
2016-10-27 13:08:16 +00:00
/**
* Filter callback for finding variation attributes .
* @ param WC_Product_Attribute $attribute
* @ return bool
*/
private static function filter_variation_attributes ( $attribute ) {
return true === $attribute -> get_variation ();
2013-08-06 10:41:20 +00:00
}
/**
2015-11-03 12:28:01 +00:00
* Show options for the variable product type .
2013-08-06 10:41:20 +00:00
*/
2013-09-24 15:21:12 +00:00
public static function output_variations () {
2016-10-27 13:08:16 +00:00
global $post , $wpdb , $product_object ;
2013-08-06 10:41:20 +00:00
2016-10-27 13:08:16 +00:00
$variation_attributes = array_filter ( $product_object -> get_attributes (), array ( __CLASS__ , 'filter_variation_attributes' ) );
$default_attributes = $product_object -> get_default_attributes ();
2015-09-02 21:11:28 +00:00
$variations_count = absint ( $wpdb -> get_var ( $wpdb -> prepare ( " SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation' AND post_status IN ('publish', 'private') " , $post -> ID ) ) );
2015-09-14 15:54:58 +00:00
$variations_per_page = absint ( apply_filters ( 'woocommerce_admin_meta_boxes_variations_per_page' , 15 ) );
2015-07-06 01:00:38 +00:00
$variations_total_pages = ceil ( $variations_count / $variations_per_page );
2016-10-27 13:08:16 +00:00
include ( 'views/html-product-data-variations.php' );
2013-08-06 10:41:20 +00:00
}
/**
2016-10-26 17:02:50 +00:00
* Prepare downloads for save .
* @ return array
2013-08-06 10:41:20 +00:00
*/
2016-10-26 17:02:50 +00:00
private static function prepare_downloads () {
$downloads = array ();
if ( isset ( $_POST [ '_wc_file_urls' ] ) ) {
$file_names = isset ( $_POST [ '_wc_file_names' ] ) ? $_POST [ '_wc_file_names' ] : array ();
$file_urls = isset ( $_POST [ '_wc_file_urls' ] ) ? wp_unslash ( array_map ( 'trim' , $_POST [ '_wc_file_urls' ] ) ) : array ();
$file_url_size = sizeof ( $file_urls );
for ( $i = 0 ; $i < $file_url_size ; $i ++ ) {
if ( ! empty ( $file_urls [ $i ] ) ) {
$downloads [] = array (
'name' => wc_clean ( $file_names [ $i ] ),
'file' => $file_urls [ $i ],
);
2013-08-06 10:41:20 +00:00
}
}
}
2016-10-26 17:02:50 +00:00
return $downloads ;
}
2014-08-31 07:18:21 +00:00
2016-10-26 17:02:50 +00:00
/**
* Prepare children for save .
* @ return array
*/
private static function prepare_children () {
return isset ( $_POST [ 'grouped_products' ] ) ? array_filter ( array_map ( 'intval' , explode ( ',' , $_POST [ 'grouped_products' ] ) ) ) : array ();
}
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
/**
* Prepare attributes for save .
* @ return array
*/
public static function prepare_attributes ( $data = false ) {
$attributes = array ();
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
if ( ! $data ) {
$data = $_POST ;
}
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
if ( isset ( $data [ 'attribute_names' ], $data [ 'attribute_values' ] ) ) {
$attribute_names = $data [ 'attribute_names' ];
$attribute_values = $data [ 'attribute_values' ];
$attribute_visibility = isset ( $data [ 'attribute_visibility' ] ) ? $data [ 'attribute_visibility' ] : array ();
$attribute_variation = isset ( $data [ 'attribute_variation' ] ) ? $data [ 'attribute_variation' ] : array ();
$attribute_position = $data [ 'attribute_position' ];
2015-06-05 12:37:45 +00:00
$attribute_names_max_key = max ( array_keys ( $attribute_names ) );
2013-08-06 10:41:20 +00:00
2015-05-19 16:53:00 +00:00
for ( $i = 0 ; $i <= $attribute_names_max_key ; $i ++ ) {
2016-10-26 17:02:50 +00:00
if ( empty ( $attribute_names [ $i ] ) || ! isset ( $attribute_values [ $i ] ) ) {
2013-08-06 10:41:20 +00:00
continue ;
2014-06-27 13:08:39 +00:00
}
2016-10-26 17:02:50 +00:00
$attribute_name = wc_clean ( $attribute_names [ $i ] );
$attribute_id = wc_attribute_taxonomy_id_by_name ( $attribute_name );
$options = isset ( $attribute_values [ $i ] ) ? $attribute_values [ $i ] : '' ;
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
if ( is_array ( $options ) ) {
// Term ids sent as array.
$options = wp_parse_id_list ( $options );
} else {
// Terms or text sent in textarea.
$options = 0 < $attribute_id ? wc_sanitize_textarea ( wc_sanitize_term_text_based ( $options ) ) : wc_sanitize_textarea ( $options );
$options = wc_get_text_attributes ( $options );
2014-06-19 15:47:04 +00:00
}
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
$attribute = new WC_Product_Attribute ();
$attribute -> set_id ( $attribute_id );
$attribute -> set_name ( $attribute_name );
$attribute -> set_options ( $options );
$attribute -> set_position ( $attribute_position [ $i ] );
$attribute -> set_visible ( isset ( $attribute_visibility [ $i ] ) );
$attribute -> set_variation ( isset ( $attribute_variation [ $i ] ) );
$attributes [] = $attribute ;
2013-08-06 10:41:20 +00:00
}
}
2016-10-26 17:02:50 +00:00
return $attributes ;
}
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
/**
* Save meta box data .
*/
public static function save ( $post_id , $post ) {
// Process product type first so we have the correct class to run setters.
$product_type = empty ( $_POST [ 'product-type' ] ) ? 'simple' : sanitize_title ( stripslashes ( $_POST [ 'product-type' ] ) );
$classname = WC_Product_Factory :: get_classname_from_product_type ( $product_type );
2013-08-20 12:52:06 +00:00
2016-10-26 17:02:50 +00:00
if ( ! class_exists ( $classname ) ) {
$classname = 'WC_Product_Simple' ;
2013-08-06 10:41:20 +00:00
}
2016-10-26 17:02:50 +00:00
$product = new $classname ( $post_id );
$errors = $product -> set_props ( array (
2016-10-27 13:08:16 +00:00
'sku' => isset ( $_POST [ '_sku' ] ) ? wc_clean ( $_POST [ '_sku' ] ) : null ,
2016-10-26 17:02:50 +00:00
'purchase_note' => wp_kses_post ( stripslashes ( $_POST [ '_purchase_note' ] ) ),
2016-10-27 13:08:16 +00:00
'downloadable' => isset ( $_POST [ '_downloadable' ] ),
2016-10-26 17:02:50 +00:00
'virtual' => isset ( $_POST [ '_virtual' ] ),
'tax_status' => wc_clean ( $_POST [ '_tax_status' ] ),
'tax_class' => wc_clean ( $_POST [ '_tax_class' ] ),
'weight' => wc_clean ( $_POST [ '_weight' ] ),
'length' => wc_clean ( $_POST [ '_length' ] ),
'width' => wc_clean ( $_POST [ '_width' ] ),
'height' => wc_clean ( $_POST [ '_height' ] ),
'shipping_class_id' => absint ( $_POST [ 'product_shipping_class' ] ),
'sold_individually' => ! empty ( $_POST [ '_sold_individually' ] ),
'upsell_ids' => array_map ( 'intval' , explode ( ',' , $_POST [ 'upsell_ids' ] ) ),
'crosssell_ids' => array_map ( 'intval' , explode ( ',' , $_POST [ 'crosssell_ids' ] ) ),
'regular_price' => wc_clean ( $_POST [ '_regular_price' ] ),
'sale_price' => wc_clean ( $_POST [ '_sale_price' ] ),
'date_on_sale_from' => wc_clean ( $_POST [ '_sale_price_dates_from' ] ),
'date_on_sale_to' => wc_clean ( $_POST [ '_sale_price_dates_to' ] ),
'manage_stock' => ! empty ( $_POST [ '_manage_stock' ] ),
'backorders' => wc_clean ( $_POST [ '_backorders' ] ),
'stock_status' => wc_clean ( $_POST [ '_stock_status' ] ),
2016-10-27 13:08:16 +00:00
'stock_quantity' => wc_stock_amount ( $_POST [ '_stock' ] ),
2016-10-26 17:02:50 +00:00
'attributes' => self :: prepare_attributes (),
'download_limit' => '' === $_POST [ '_download_limit' ] ? '' : absint ( $_POST [ '_download_limit' ] ),
'download_expiry' => '' === $_POST [ '_download_expiry' ] ? '' : absint ( $_POST [ '_download_expiry' ] ),
'downloads' => self :: prepare_downloads (),
'product_url' => esc_url_raw ( $_POST [ '_product_url' ] ),
'button_text' => wc_clean ( $_POST [ '_button_text' ] ),
'children' => 'grouped' === $product_type ? self :: prepare_children () : null ,
2016-10-27 13:08:16 +00:00
'reviews_allowed' => ! empty ( $_POST [ '_reviews_allowed' ] ),
2016-10-26 17:02:50 +00:00
) );
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
if ( is_wp_error ( $errors ) ) {
WC_Admin_Meta_Boxes :: add_error ( $errors -> get_error_message () );
2014-06-19 11:25:07 +00:00
}
2013-08-06 10:41:20 +00:00
2016-10-26 17:02:50 +00:00
$product -> save ();
2015-06-16 14:10:53 +00:00
2013-08-06 10:41:20 +00:00
do_action ( 'woocommerce_process_product_meta_' . $product_type , $post_id );
}
/**
2015-11-03 12:28:01 +00:00
* Save meta box data .
2015-07-06 04:50:20 +00:00
*
2016-01-04 21:31:36 +00:00
* @ param int $post_id
* @ param WP_Post $post
2013-08-06 10:41:20 +00:00
*/
public static function save_variations ( $post_id , $post ) {
2014-06-19 15:47:04 +00:00
global $wpdb ;
2013-08-06 10:41:20 +00:00
2013-08-13 15:56:09 +00:00
$attributes = ( array ) maybe_unserialize ( get_post_meta ( $post_id , '_product_attributes' , true ) );
2013-08-06 10:41:20 +00:00
if ( isset ( $_POST [ 'variable_sku' ] ) ) {
2014-06-19 15:47:04 +00:00
$variable_post_id = $_POST [ 'variable_post_id' ];
$variable_sku = $_POST [ 'variable_sku' ];
$variable_regular_price = $_POST [ 'variable_regular_price' ];
$variable_sale_price = $_POST [ 'variable_sale_price' ];
$upload_image_id = $_POST [ 'upload_image_id' ];
$variable_download_limit = $_POST [ 'variable_download_limit' ];
$variable_download_expiry = $_POST [ 'variable_download_expiry' ];
$variable_shipping_class = $_POST [ 'variable_shipping_class' ];
$variable_tax_class = isset ( $_POST [ 'variable_tax_class' ] ) ? $_POST [ 'variable_tax_class' ] : array ();
$variable_menu_order = $_POST [ 'variation_menu_order' ];
$variable_sale_price_dates_from = $_POST [ 'variable_sale_price_dates_from' ];
$variable_sale_price_dates_to = $_POST [ 'variable_sale_price_dates_to' ];
2014-06-27 12:45:50 +00:00
2014-06-19 15:47:04 +00:00
$variable_weight = isset ( $_POST [ 'variable_weight' ] ) ? $_POST [ 'variable_weight' ] : array ();
$variable_length = isset ( $_POST [ 'variable_length' ] ) ? $_POST [ 'variable_length' ] : array ();
$variable_width = isset ( $_POST [ 'variable_width' ] ) ? $_POST [ 'variable_width' ] : array ();
$variable_height = isset ( $_POST [ 'variable_height' ] ) ? $_POST [ 'variable_height' ] : array ();
$variable_enabled = isset ( $_POST [ 'variable_enabled' ] ) ? $_POST [ 'variable_enabled' ] : array ();
$variable_is_virtual = isset ( $_POST [ 'variable_is_virtual' ] ) ? $_POST [ 'variable_is_virtual' ] : array ();
$variable_is_downloadable = isset ( $_POST [ 'variable_is_downloadable' ] ) ? $_POST [ 'variable_is_downloadable' ] : array ();
2014-06-27 12:45:50 +00:00
2014-06-19 15:47:04 +00:00
$variable_manage_stock = isset ( $_POST [ 'variable_manage_stock' ] ) ? $_POST [ 'variable_manage_stock' ] : array ();
$variable_stock = isset ( $_POST [ 'variable_stock' ] ) ? $_POST [ 'variable_stock' ] : array ();
$variable_backorders = isset ( $_POST [ 'variable_backorders' ] ) ? $_POST [ 'variable_backorders' ] : array ();
$variable_stock_status = isset ( $_POST [ 'variable_stock_status' ] ) ? $_POST [ 'variable_stock_status' ] : array ();
2013-08-06 10:41:20 +00:00
2015-05-14 17:56:26 +00:00
$variable_description = isset ( $_POST [ 'variable_description' ] ) ? $_POST [ 'variable_description' ] : array ();
2013-08-06 10:41:20 +00:00
$max_loop = max ( array_keys ( $_POST [ 'variable_post_id' ] ) );
for ( $i = 0 ; $i <= $max_loop ; $i ++ ) {
2014-06-19 15:47:04 +00:00
if ( ! isset ( $variable_post_id [ $i ] ) ) {
2013-08-06 10:41:20 +00:00
continue ;
2014-06-19 15:47:04 +00:00
}
2013-08-06 10:41:20 +00:00
2014-06-27 13:08:39 +00:00
$variation_id = absint ( $variable_post_id [ $i ] );
2014-06-27 12:45:50 +00:00
2014-06-19 15:47:04 +00:00
// Checkboxes
2015-07-24 05:12:31 +00:00
$is_virtual = isset ( $variable_is_virtual [ $i ] ) ? 'yes' : 'no' ;
$is_downloadable = isset ( $variable_is_downloadable [ $i ] ) ? 'yes' : 'no' ;
$post_status = isset ( $variable_enabled [ $i ] ) ? 'publish' : 'private' ;
$manage_stock = isset ( $variable_manage_stock [ $i ] ) ? 'yes' : 'no' ;
2014-06-27 12:45:50 +00:00
2013-08-06 10:41:20 +00:00
// Generate a useful post title
2016-09-01 20:50:14 +00:00
$variation_post_title = sprintf ( __ ( 'Variation #%1$s of %2$s' , 'woocommerce' ), absint ( $variation_id ), esc_html ( get_the_title ( $post_id ) ) );
2013-08-06 10:41:20 +00:00
// Update or Add post
if ( ! $variation_id ) {
$variation = array (
2014-06-27 13:08:39 +00:00
'post_title' => $variation_post_title ,
'post_content' => '' ,
'post_status' => $post_status ,
'post_author' => get_current_user_id (),
'post_parent' => $post_id ,
'post_type' => 'product_variation' ,
2016-08-27 01:46:45 +00:00
'menu_order' => $variable_menu_order [ $i ],
2013-08-06 10:41:20 +00:00
);
$variation_id = wp_insert_post ( $variation );
do_action ( 'woocommerce_create_product_variation' , $variation_id );
} else {
2015-11-20 17:09:47 +00:00
$modified_date = date_i18n ( 'Y-m-d H:i:s' , current_time ( 'timestamp' ) );
2015-11-20 17:00:10 +00:00
$wpdb -> update ( $wpdb -> posts , array (
'post_status' => $post_status ,
'post_title' => $variation_post_title ,
'menu_order' => $variable_menu_order [ $i ],
'post_modified' => $modified_date ,
2016-08-27 01:46:45 +00:00
'post_modified_gmt' => get_gmt_from_date ( $modified_date ),
2015-11-20 17:00:10 +00:00
), array ( 'ID' => $variation_id ) );
2013-08-06 10:41:20 +00:00
2015-10-01 14:48:37 +00:00
clean_post_cache ( $variation_id );
2013-08-06 10:41:20 +00:00
do_action ( 'woocommerce_update_product_variation' , $variation_id );
}
2014-05-06 09:47:23 +00:00
// Only continue if we have a variation ID
if ( ! $variation_id ) {
continue ;
}
2014-06-27 12:45:50 +00:00
// Unique SKU
$sku = get_post_meta ( $variation_id , '_sku' , true );
2015-12-02 11:22:09 +00:00
$new_sku = wc_clean ( $variable_sku [ $i ] );
2014-06-27 12:45:50 +00:00
2014-06-27 13:08:39 +00:00
if ( '' == $new_sku ) {
2014-06-27 12:45:50 +00:00
update_post_meta ( $variation_id , '_sku' , '' );
} elseif ( $new_sku !== $sku ) {
if ( ! empty ( $new_sku ) ) {
2014-06-27 19:03:25 +00:00
$unique_sku = wc_product_has_unique_sku ( $variation_id , $new_sku );
2014-08-31 07:18:21 +00:00
2014-06-27 18:58:29 +00:00
if ( ! $unique_sku ) {
2015-07-27 17:16:52 +00:00
WC_Admin_Meta_Boxes :: add_error ( sprintf ( __ ( '#%s – Variation SKU must be unique.' , 'woocommerce' ), $variation_id ) );
2014-06-27 12:45:50 +00:00
} else {
update_post_meta ( $variation_id , '_sku' , $new_sku );
}
} else {
update_post_meta ( $variation_id , '_sku' , '' );
}
}
2013-08-06 10:41:20 +00:00
// Update post meta
update_post_meta ( $variation_id , '_thumbnail_id' , absint ( $upload_image_id [ $i ] ) );
2013-11-25 13:34:21 +00:00
update_post_meta ( $variation_id , '_virtual' , wc_clean ( $is_virtual ) );
update_post_meta ( $variation_id , '_downloadable' , wc_clean ( $is_downloadable ) );
2013-08-06 10:41:20 +00:00
2014-06-27 13:08:39 +00:00
if ( isset ( $variable_weight [ $i ] ) ) {
update_post_meta ( $variation_id , '_weight' , ( '' === $variable_weight [ $i ] ) ? '' : wc_format_decimal ( $variable_weight [ $i ] ) );
}
2014-08-31 07:18:21 +00:00
2014-06-27 13:08:39 +00:00
if ( isset ( $variable_length [ $i ] ) ) {
update_post_meta ( $variation_id , '_length' , ( '' === $variable_length [ $i ] ) ? '' : wc_format_decimal ( $variable_length [ $i ] ) );
}
2014-08-31 07:18:21 +00:00
2014-06-27 13:08:39 +00:00
if ( isset ( $variable_width [ $i ] ) ) {
update_post_meta ( $variation_id , '_width' , ( '' === $variable_width [ $i ] ) ? '' : wc_format_decimal ( $variable_width [ $i ] ) );
}
2014-08-31 07:18:21 +00:00
2014-06-27 13:08:39 +00:00
if ( isset ( $variable_height [ $i ] ) ) {
update_post_meta ( $variation_id , '_height' , ( '' === $variable_height [ $i ] ) ? '' : wc_format_decimal ( $variable_height [ $i ] ) );
}
2013-10-01 16:54:29 +00:00
2013-08-13 15:56:09 +00:00
// Stock handling
2014-06-19 15:47:04 +00:00
update_post_meta ( $variation_id , '_manage_stock' , $manage_stock );
2014-06-24 12:02:09 +00:00
if ( 'yes' === $manage_stock ) {
2014-08-15 14:22:43 +00:00
update_post_meta ( $variation_id , '_backorders' , wc_clean ( $variable_backorders [ $i ] ) );
2014-06-25 10:25:28 +00:00
wc_update_product_stock ( $variation_id , wc_stock_amount ( $variable_stock [ $i ] ) );
2014-05-06 09:47:23 +00:00
} else {
2014-04-22 01:13:13 +00:00
delete_post_meta ( $variation_id , '_backorders' );
2016-10-27 13:08:16 +00:00
wc_update_product_stock ( $variation_id , '' );
2014-05-06 09:47:23 +00:00
}
2013-08-13 15:56:09 +00:00
2016-05-24 13:38:54 +00:00
// Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level
if ( ! empty ( $variable_stock_status [ $i ] ) ) {
wc_update_product_stock_status ( $variation_id , $variable_stock_status [ $i ] );
}
2013-08-06 10:41:20 +00:00
// Price handling
2016-09-06 10:37:20 +00:00
_wc_save_product_price ( $variation_id , $variable_regular_price [ $i ], $variable_sale_price [ $i ], $variable_sale_price_dates_from [ $i ], $variable_sale_price_dates_to [ $i ] );
2013-08-06 10:41:20 +00:00
2016-09-09 00:14:28 +00:00
if ( isset ( $variable_tax_class [ $i ] ) && 'parent' !== $variable_tax_class [ $i ] ) {
2013-11-25 13:34:21 +00:00
update_post_meta ( $variation_id , '_tax_class' , wc_clean ( $variable_tax_class [ $i ] ) );
2014-06-19 15:47:04 +00:00
} else {
2013-08-06 10:41:20 +00:00
delete_post_meta ( $variation_id , '_tax_class' );
2014-06-19 15:47:04 +00:00
}
2013-08-06 10:41:20 +00:00
2014-06-27 13:08:39 +00:00
if ( 'yes' == $is_downloadable ) {
2013-11-25 13:34:21 +00:00
update_post_meta ( $variation_id , '_download_limit' , wc_clean ( $variable_download_limit [ $i ] ) );
update_post_meta ( $variation_id , '_download_expiry' , wc_clean ( $variable_download_expiry [ $i ] ) );
2013-08-06 10:41:20 +00:00
2015-05-26 15:51:11 +00:00
$files = array ();
$file_names = isset ( $_POST [ '_wc_variation_file_names' ][ $variation_id ] ) ? array_map ( 'wc_clean' , $_POST [ '_wc_variation_file_names' ][ $variation_id ] ) : array ();
$file_urls = isset ( $_POST [ '_wc_variation_file_urls' ][ $variation_id ] ) ? array_map ( 'wc_clean' , $_POST [ '_wc_variation_file_urls' ][ $variation_id ] ) : array ();
$file_url_size = sizeof ( $file_urls );
$allowed_file_types = get_allowed_mime_types ();
2013-09-20 16:01:09 +00:00
2013-09-24 15:21:12 +00:00
for ( $ii = 0 ; $ii < $file_url_size ; $ii ++ ) {
2014-06-19 15:47:04 +00:00
if ( ! empty ( $file_urls [ $ii ] ) ) {
2015-05-26 15:49:41 +00:00
// Find type and file URL
if ( 0 === strpos ( $file_urls [ $ii ], 'http' ) ) {
$file_is = 'absolute' ;
$file_url = esc_url_raw ( $file_urls [ $ii ] );
} elseif ( '[' === substr ( $file_urls [ $ii ], 0 , 1 ) && ']' === substr ( $file_urls [ $ii ], - 1 ) ) {
$file_is = 'shortcode' ;
$file_url = wc_clean ( $file_urls [ $ii ] );
} else {
$file_is = 'relative' ;
$file_url = wc_clean ( $file_urls [ $ii ] );
}
$file_name = wc_clean ( $file_names [ $ii ] );
$file_hash = md5 ( $file_url );
// Validate the file extension
if ( in_array ( $file_is , array ( 'absolute' , 'relative' ) ) ) {
2015-10-06 14:01:41 +00:00
$file_type = wp_check_filetype ( strtok ( $file_url , '?' ), $allowed_file_types );
2015-05-26 15:49:41 +00:00
$parsed_url = parse_url ( $file_url , PHP_URL_PATH );
$extension = pathinfo ( $parsed_url , PATHINFO_EXTENSION );
if ( ! empty ( $extension ) && ! in_array ( $file_type [ 'type' ], $allowed_file_types ) ) {
2016-09-01 20:50:14 +00:00
WC_Admin_Meta_Boxes :: add_error ( sprintf ( __ ( '#%1$s – The downloadable file %2$s cannot be used as it does not have an allowed file type. Allowed types include: %3$s' , 'woocommerce' ), $variation_id , '<code>' . basename ( $file_url ) . '</code>' , '<code>' . implode ( ', ' , array_keys ( $allowed_file_types ) ) . '</code>' ) );
2015-05-26 15:49:41 +00:00
continue ;
}
}
// Validate the file exists
2015-06-09 14:27:28 +00:00
if ( 'relative' === $file_is && ! apply_filters ( 'woocommerce_downloadable_file_exists' , file_exists ( $file_url ), $file_url ) ) {
2016-09-01 20:50:14 +00:00
WC_Admin_Meta_Boxes :: add_error ( sprintf ( __ ( '#%1$s – The downloadable file %2$s cannot be used as it does not exist on the server.' , 'woocommerce' ), $variation_id , '<code>' . $file_url . '</code>' ) );
2015-05-26 15:49:41 +00:00
continue ;
}
2014-08-31 07:18:21 +00:00
2015-05-26 15:49:41 +00:00
$files [ $file_hash ] = array (
'name' => $file_name ,
2016-08-27 01:46:45 +00:00
'file' => $file_url ,
2013-09-20 16:01:09 +00:00
);
2014-06-19 15:47:04 +00:00
}
2013-08-06 10:41:20 +00:00
}
2013-09-20 16:01:09 +00:00
// grant permission to any newly added files on any existing orders for this product prior to saving
do_action ( 'woocommerce_process_product_file_download_paths' , $post_id , $variation_id , $files );
2013-08-06 10:41:20 +00:00
2013-09-20 16:01:09 +00:00
update_post_meta ( $variation_id , '_downloadable_files' , $files );
2013-08-06 10:41:20 +00:00
} else {
update_post_meta ( $variation_id , '_download_limit' , '' );
update_post_meta ( $variation_id , '_download_expiry' , '' );
2013-09-20 16:01:09 +00:00
update_post_meta ( $variation_id , '_downloadable_files' , '' );
2013-08-06 10:41:20 +00:00
}
2015-05-28 21:31:45 +00:00
update_post_meta ( $variation_id , '_variation_description' , wp_kses_post ( $variable_description [ $i ] ) );
2015-06-05 12:37:45 +00:00
2013-08-06 10:41:20 +00:00
// Save shipping class
2013-09-24 15:21:12 +00:00
$variable_shipping_class [ $i ] = ! empty ( $variable_shipping_class [ $i ] ) ? ( int ) $variable_shipping_class [ $i ] : '' ;
2016-09-02 01:33:57 +00:00
wp_set_object_terms ( $variation_id , $variable_shipping_class [ $i ], 'product_shipping_class' );
2013-08-06 10:41:20 +00:00
2015-06-11 13:43:02 +00:00
// Update Attributes
2014-05-06 09:47:23 +00:00
$updated_attribute_keys = array ();
2013-08-06 10:41:20 +00:00
foreach ( $attributes as $attribute ) {
if ( $attribute [ 'is_variation' ] ) {
2015-06-11 13:43:02 +00:00
$attribute_key = 'attribute_' . sanitize_title ( $attribute [ 'name' ] );
2014-05-06 09:47:23 +00:00
$updated_attribute_keys [] = $attribute_key ;
2015-06-11 13:43:02 +00:00
if ( $attribute [ 'is_taxonomy' ] ) {
// Don't use wc_clean as it destroys sanitized characters
$value = isset ( $_POST [ $attribute_key ][ $i ] ) ? sanitize_title ( stripslashes ( $_POST [ $attribute_key ][ $i ] ) ) : '' ;
} else {
$value = isset ( $_POST [ $attribute_key ][ $i ] ) ? wc_clean ( stripslashes ( $_POST [ $attribute_key ][ $i ] ) ) : '' ;
}
2014-05-06 09:47:23 +00:00
update_post_meta ( $variation_id , $attribute_key , $value );
2013-08-06 10:41:20 +00:00
}
2014-05-06 09:47:23 +00:00
}
// Remove old taxonomies attributes so data is kept up to date - first get attribute key names
$delete_attribute_keys = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT meta_key FROM { $wpdb -> postmeta } WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( ' " . implode ( " ',' " , $updated_attribute_keys ) . " ' ) AND post_id = %d; " , $variation_id ) );
2013-08-06 10:41:20 +00:00
2014-05-06 09:47:23 +00:00
foreach ( $delete_attribute_keys as $key ) {
delete_post_meta ( $variation_id , $key );
2013-08-06 10:41:20 +00:00
}
2013-10-21 11:37:27 +00:00
do_action ( 'woocommerce_save_product_variation' , $variation_id , $i );
2013-09-24 15:21:12 +00:00
}
2013-08-06 10:41:20 +00:00
}
// Update parent if variable so price sorting works and stays in sync with the cheapest child
WC_Product_Variable :: sync ( $post_id );
// Update default attribute options setting
$default_attributes = array ();
foreach ( $attributes as $attribute ) {
2014-08-31 07:18:21 +00:00
2013-08-06 10:41:20 +00:00
if ( $attribute [ 'is_variation' ] ) {
2015-07-24 05:12:31 +00:00
$value = '' ;
2013-08-06 10:41:20 +00:00
2014-06-27 13:08:39 +00:00
if ( isset ( $_POST [ 'default_attribute_' . sanitize_title ( $attribute [ 'name' ] ) ] ) ) {
2015-07-24 05:12:31 +00:00
if ( $attribute [ 'is_taxonomy' ] ) {
// Don't use wc_clean as it destroys sanitized characters
$value = sanitize_title ( trim ( stripslashes ( $_POST [ 'default_attribute_' . sanitize_title ( $attribute [ 'name' ] ) ] ) ) );
} else {
$value = wc_clean ( trim ( stripslashes ( $_POST [ 'default_attribute_' . sanitize_title ( $attribute [ 'name' ] ) ] ) ) );
}
2014-06-27 13:08:39 +00:00
}
2013-08-06 10:41:20 +00:00
2014-06-27 13:08:39 +00:00
if ( $value ) {
2013-08-06 10:41:20 +00:00
$default_attributes [ sanitize_title ( $attribute [ 'name' ] ) ] = $value ;
2014-06-27 13:08:39 +00:00
}
2013-08-06 10:41:20 +00:00
}
}
update_post_meta ( $post_id , '_default_attributes' , $default_attributes );
}
2014-03-27 23:37:00 +00:00
}