Rather than have hooks *everywhere* use a single set stock function in admin and on the frontend Closes #3593

This commit is contained in:
Mike Jolley 2013-08-13 16:56:09 +01:00
parent 8db53a8d9d
commit d021980c10
6 changed files with 120 additions and 208 deletions

View File

@ -151,26 +151,33 @@ class WC_Product {
/**
* Set stock level of the product.
*
* @access public
* @param mixed $amount (default: null)
* @return int Stock
*/
public function set_stock( $amount = null ) {
global $woocommerce;
if ( is_null( $amount ) )
return;
if ( $this->managing_stock() && ! is_null( $amount ) ) {
if ( $this->managing_stock() ) {
// Update stock amount
$this->stock = intval( $amount );
// Update meta
update_post_meta( $this->id, '_stock', $this->stock );
do_action( 'woocommerce_product_set_stock', $this );
// Out of stock attribute
// Update stock status
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
elseif ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
wc_delete_product_transients( $this->id ); // Clear transient
// Clear total stock transient
delete_transient( 'wc_product_total_stock_' . $this->id );
// Trigger action
do_action( 'woocommerce_product_set_stock', $this );
return $this->get_stock_quantity();
}
@ -179,53 +186,21 @@ class WC_Product {
/**
* Reduce stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to reduce by.
* @return int Stock
*/
public function reduce_stock( $by = 1 ) {
global $woocommerce;
if ( $this->managing_stock() ) {
$this->stock = $this->stock - $by;
update_post_meta( $this->id, '_stock', $this->stock );
do_action( 'woocommerce_product_reduce_stock', $this, $by );
// Out of stock attribute
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
wc_delete_product_transients( $this->id ); // Clear transient
return $this->get_stock_quantity();
}
return $this->set_stock( $this->stock - $by );
}
/**
* Increase stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to increase by
* @return int Stock
*/
public function increase_stock( $by = 1 ) {
global $woocommerce;
if ( $this->managing_stock() ) {
$this->stock = $this->stock + $by;
update_post_meta( $this->id, '_stock', $this->stock );
do_action( 'woocommerce_product_increase_stock', $this, $by );
// Out of stock attribute
if ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
wc_delete_product_transients( $this->id ); // Clear transient
return $this->get_stock_quantity();
}
return $this->set_stock( $this->stock + $by );
}
/**

View File

@ -151,7 +151,7 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
if ( isset( $_POST['_visibility'] ) )
update_post_meta( $post_id, '_visibility', stripslashes( $_POST['_visibility'] ) );
if ( isset( $_POST['_stock_status'] ) )
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_POST['_stock_status'] ) );
}
/**
@ -683,7 +683,6 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
if ( isset( $_REQUEST['_length'] ) ) update_post_meta( $post_id, '_length', woocommerce_clean( $_REQUEST['_length'] ) );
if ( isset( $_REQUEST['_width'] ) ) update_post_meta( $post_id, '_width', woocommerce_clean( $_REQUEST['_width'] ) );
if ( isset( $_REQUEST['_height'] ) ) update_post_meta( $post_id, '_height', woocommerce_clean( $_REQUEST['_height'] ) );
if ( isset( $_REQUEST['_stock_status'] ) ) update_post_meta( $post_id, '_stock_status', woocommerce_clean( $_REQUEST['_stock_status'] ) );
if ( isset( $_REQUEST['_visibility'] ) ) update_post_meta( $post_id, '_visibility', woocommerce_clean( $_REQUEST['_visibility'] ) );
if ( isset( $_REQUEST['_featured'] ) ) update_post_meta( $post_id, '_featured', 'yes' ); else update_post_meta( $post_id, '_featured', 'no' );
@ -716,14 +715,18 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
}
}
// Handle stock status
if ( isset( $_REQUEST['_stock_status'] ) )
wc_update_product_stock_status( $post_id, woocommerce_clean( $_REQUEST['_stock_status'] ) );
// Handle stock
if ( ! $product->is_type('grouped') ) {
if ( isset( $_REQUEST['_manage_stock'] ) ) {
update_post_meta( $post_id, '_manage_stock', 'yes' );
update_post_meta( $post_id, '_stock', (int) $_REQUEST['_stock'] );
wc_update_product_stock( $post_id, intval( $_REQUEST['_stock'] ) );
} else {
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_stock', '0' );
wc_update_product_stock( $post_id, 0 );
}
}
@ -762,7 +765,7 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
}
if ( ! empty( $_REQUEST['_stock_status'] ) )
update_post_meta( $post_id, '_stock_status', stripslashes( $_REQUEST['_stock_status'] ) );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_REQUEST['_stock_status'] ) );
if ( ! empty( $_REQUEST['_visibility'] ) )
update_post_meta( $post_id, '_visibility', stripslashes( $_REQUEST['_visibility'] ) );
@ -872,8 +875,8 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
if ( ! $product->is_type( 'grouped' ) ) {
if ( ! empty( $_REQUEST['change_stock'] ) ) {
update_post_meta( $post_id, '_stock', (int) $_REQUEST['_stock'] );
update_post_meta( $post_id, '_manage_stock', 'yes' );
wc_update_product_stock( $post_id, intval( $_REQUEST['_stock'] ) );
}
if ( ! empty( $_REQUEST['_manage_stock'] ) ) {
@ -882,7 +885,7 @@ class WC_Admin_CPT_Product extends WC_Admin_CPT {
update_post_meta( $post_id, '_manage_stock', 'yes' );
} else {
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_stock', '0' );
wc_update_product_stock( $post_id, 0 );
}
}

View File

@ -1148,44 +1148,40 @@ class WC_Meta_Box_Product_Data {
if ( $product_type == 'grouped' ) {
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
update_post_meta( $post_id, '_stock', '' );
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_backorders', 'no' );
update_post_meta( $post_id, '_stock', '' );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_POST['_stock_status'] ) );
} elseif ( $product_type == 'external' ) {
update_post_meta( $post_id, '_stock_status', 'instock' );
update_post_meta( $post_id, '_stock', '' );
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_backorders', 'no' );
update_post_meta( $post_id, '_stock', '' );
wc_update_product_stock_status( $post_id, 'instock' );
} elseif ( ! empty( $_POST['_manage_stock'] ) ) {
// Manage stock
update_post_meta( $post_id, '_stock', (int) $_POST['_stock'] );
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
update_post_meta( $post_id, '_backorders', stripslashes( $_POST['_backorders'] ) );
update_post_meta( $post_id, '_manage_stock', 'yes' );
update_post_meta( $post_id, '_backorders', woocommerce_clean( $_POST['_backorders'] ) );
// Check stock level
if ( $product_type !== 'variable' && $_POST['_backorders'] == 'no' && (int) $_POST['_stock'] < 1 )
update_post_meta( $post_id, '_stock_status', 'outofstock' );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_POST['_stock_status'] ) );
wc_update_product_stock( $post_id, intval( $_POST['_stock'] ) );
} else {
// Don't manage stock
update_post_meta( $post_id, '_stock', '' );
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
update_post_meta( $post_id, '_backorders', stripslashes( $_POST['_backorders'] ) );
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_backorders', woocommerce_clean( $_POST['_backorders'] ) );
update_post_meta( $post_id, '_stock', '' );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_POST['_stock_status'] ) );
}
} else {
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
wc_update_product_stock_status( $post_id, woocommerce_clean( $_POST['_stock_status'] ) );
}
// Upsells
@ -1274,6 +1270,8 @@ class WC_Meta_Box_Product_Data {
public static function save_variations( $post_id, $post ) {
global $woocommerce, $wpdb;
$attributes = (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) );
if ( isset( $_POST['variable_sku'] ) ) {
$variable_post_id = $_POST['variable_post_id'];
@ -1299,8 +1297,6 @@ class WC_Meta_Box_Product_Data {
$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();
$attributes = (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) );
$max_loop = max( array_keys( $_POST['variable_post_id'] ) );
for ( $i = 0; $i <= $max_loop; $i ++ ) {
@ -1348,17 +1344,16 @@ class WC_Meta_Box_Product_Data {
// Update post meta
update_post_meta( $variation_id, '_sku', woocommerce_clean( $variable_sku[ $i ] ) );
update_post_meta( $variation_id, '_weight', woocommerce_clean( $variable_weight[ $i ] ) );
update_post_meta( $variation_id, '_length', woocommerce_clean( $variable_length[ $i ] ) );
update_post_meta( $variation_id, '_width', woocommerce_clean( $variable_width[ $i ] ) );
update_post_meta( $variation_id, '_height', woocommerce_clean( $variable_height[ $i ] ) );
update_post_meta( $variation_id, '_stock', woocommerce_clean( $variable_stock[ $i ] ) );
update_post_meta( $variation_id, '_thumbnail_id', absint( $upload_image_id[ $i ] ) );
update_post_meta( $variation_id, '_virtual', woocommerce_clean( $is_virtual ) );
update_post_meta( $variation_id, '_downloadable', woocommerce_clean( $is_downloadable ) );
// Stock handling
wc_update_product_stock( $variation_id, woocommerce_clean( $variable_stock[ $i ] ) );
// Price handling
$regular_price = woocommerce_clean( $variable_regular_price[ $i ] );
$sale_price = woocommerce_clean( $variable_sale_price[ $i ] );

View File

@ -68,83 +68,17 @@ class WC_Product_Variable extends WC_Product {
/**
* Set stock level of the product.
*
* @access public
* @param mixed $amount (default: null)
* @return int Stock
*/
function set_stock( $amount = null ) {
global $woocommerce;
// Empty total stock so its refreshed
$this->total_stock = '';
if ( $this->managing_stock() && ! is_null( $amount ) ) {
$this->stock = intval( $amount );
$this->total_stock = intval( $amount );
update_post_meta( $this->id, '_stock', $this->stock );
// Check parents out of stock attribute
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
elseif ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
wc_delete_product_transients( $this->id ); // Clear transient
return apply_filters( 'woocommerce_stock_amount', $this->stock );
}
// Call parent set_stock
return parent::set_stock( $amount );
}
/**
* Reduce stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to reduce by.
* @return int Stock
*/
public function reduce_stock( $by = 1 ) {
global $woocommerce;
if ( $this->managing_stock() ) {
$this->stock = $this->stock - $by;
$this->total_stock = $this->get_total_stock() - $by;
update_post_meta($this->id, '_stock', $this->stock);
// Out of stock attribute
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
wc_delete_product_transients( $this->id ); // Clear transient
return apply_filters( 'woocommerce_stock_amount', $this->stock );
}
}
/**
* Increase stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to increase by
* @return int Stock
*/
public function increase_stock( $by = 1 ) {
global $woocommerce;
if ($this->managing_stock()) :
$this->stock = $this->stock + $by;
$this->total_stock = $this->get_total_stock() + $by;
update_post_meta($this->id, '_stock', $this->stock);
// Out of stock attribute
if ( $this->backorders_allowed() || $this->get_total_stock() > 0 )
$this->set_stock_status( 'instock' );
wc_delete_product_transients( $this->id ); // Clear transient
return apply_filters( 'woocommerce_stock_amount', $this->stock );
endif;
}
/**
* Return the products children posts.
*

View File

@ -281,76 +281,71 @@ class WC_Product_Variation extends WC_Product {
}
/**
* Set stock level of the product.
* Set stock level of the product variation.
*
* @access public
* @param mixed $amount (default: null)
* @return int Stock
* @param int $amount
* @param boolean $force_variation_stock If true, the variation's stock will be updated and not the parents.
*/
function set_stock( $amount = null ) {
global $woocommerce;
function set_stock( $amount = null, $force_variation_stock = false ) {
if ( is_null( $amount ) )
return;
if ( $this->variation_has_stock ) {
if ( $this->managing_stock() && ! is_null( $amount ) ) {
if ( $amount === '' && $force_variation_stock ) {
$this->stock = intval( $amount );
$this->total_stock = intval( $amount );
update_post_meta( $this->variation_id, '_stock', $this->stock );
wc_delete_product_transients( $this->id ); // Clear transient
// If amount is an empty string, stock management is being turned off at variation level
$this->variation_has_stock = false;
$this->stock = '';
unset( $this->manage_stock );
// Check parents out of stock attribute
if ( ! $this->is_in_stock() ) {
// Update meta
update_post_meta( $this->variation_id, '_stock', '' );
// Check parent
$parent_product = get_product( $this->id );
} elseif ( $this->variation_has_stock || $force_variation_stock ) {
// Only continue if the parent has backorders off
if ( ! $parent_product->backorders_allowed() && $parent_product->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
// Update stock amount
$this->stock = intval( $amount );
} elseif ( $this->is_in_stock() ) {
$this->set_stock_status( 'instock' );
}
// Update meta
update_post_meta( $this->variation_id, '_stock', $this->stock );
return apply_filters( 'woocommerce_stock_amount', $this->stock );
// Clear total stock transient
delete_transient( 'wc_product_total_stock_' . $this->id );
// Check parents out of stock attribute
if ( ! $this->is_in_stock() ) {
// Check parent
$parent_product = get_product( $this->id );
// Only continue if the parent has backorders off
if ( ! $parent_product->backorders_allowed() && $parent_product->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
} elseif ( $this->is_in_stock() ) {
$this->set_stock_status( 'instock' );
}
// Trigger action
do_action( 'woocommerce_product_set_stock', $this );
return $this->get_stock_quantity();
} else {
return parent::set_stock( $amount );
}
}
/**
* Reduce stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to reduce by
* @return int stock level
*/
public function reduce_stock( $by = 1 ) {
global $woocommerce;
if ( $this->variation_has_stock ) {
if ( $this->managing_stock() ) {
$this->stock = $this->stock - $by;
$this->total_stock = $this->total_stock - $by;
update_post_meta( $this->variation_id, '_stock', $this->stock );
wc_delete_product_transients( $this->id ); // Clear transient
// Check parents out of stock attribute
if ( ! $this->is_in_stock() ) {
// Check parent
$parent_product = get_product( $this->id );
// Only continue if the parent has backorders off
if ( ! $parent_product->backorders_allowed() && $parent_product->get_total_stock() <= 0 )
$this->set_stock_status( 'outofstock' );
}
return apply_filters( 'woocommerce_stock_amount', $this->stock );
}
return $this->set_stock( $this->stock - $by );
} else {
return parent::reduce_stock( $by );
}
@ -359,30 +354,15 @@ class WC_Product_Variation extends WC_Product {
/**
* Increase stock level of the product.
*
* @access public
* @param int $by (default: 1) Amount to increase by
* @return int stock level
*/
public function increase_stock( $by = 1 ) {
global $woocommerce;
if ($this->variation_has_stock) :
if ($this->managing_stock()) :
$this->stock = $this->stock + $by;
$this->total_stock = $this->total_stock + $by;
update_post_meta( $this->variation_id, '_stock', $this->stock );
wc_delete_product_transients( $this->id ); // Clear transient
// Parents out of stock attribute
if ( $this->is_in_stock() )
$this->set_stock_status( 'instock' );
return apply_filters( 'woocommerce_stock_amount', $this->stock );
endif;
else :
if ( $this->variation_has_stock ) {
return $this->set_stock( $this->stock + $by );
} else {
return parent::increase_stock( $by );
endif;
}
}
/**

View File

@ -13,7 +13,6 @@
/**
* Main function for returning products, uses the WC_Product_Factory class.
*
* @access public
* @param mixed $the_product Post object or post ID of the product.
* @param array $args (default: array()) Contains all arguments to be used to get this product.
* @return WC_Product
@ -23,6 +22,32 @@ function get_product( $the_product = false, $args = array() ) {
return $woocommerce->product_factory->get_product( $the_product, $args );
}
/**
* Update a product's stock amount
*
* @param int $product_id
* @param int $new_stock_level
*/
function wc_update_product_stock( $product_id, $new_stock_level ) {
$product = get_product( $product_id );
if ( $product->is_type( 'variation' ) )
$product->set_stock( $new_stock_level, true );
else
$product->set_stock( $new_stock_level );
}
/**
* Update a product's stock status
*
* @param int $product_id
* @param int $status
*/
function wc_update_product_stock_status( $product_id, $status ) {
$product = get_product( $product_id );
$product-> set_stock_status( $status );
}
/**
* Clear all transients cache for product data.
*