Availability html

This commit is contained in:
Mike Jolley 2016-10-20 15:02:25 +01:00
parent 0520f73a6b
commit 61a866f8f0
9 changed files with 541 additions and 501 deletions

View File

@ -59,6 +59,129 @@ abstract class WC_Abstract_Legacy_Product extends WC_Data {
return wc_get_product( $child_id );
}
/**
* Functions for getting parts of a price, in html, used by get_price_html.
*
* @deprecated 2.7.0
* @return string
*/
public function get_price_html_from_text() {
_deprecated_function( 'WC_Product::get_price_html_from_text', '2.7' );
$from = '<span class="from">' . _x( 'From:', 'min_price', 'woocommerce' ) . ' </span>';
return apply_filters( 'woocommerce_get_price_html_from_text', $from, $this );
}
/**
* Functions for getting parts of a price, in html, used by get_price_html.
*
* @deprecated 2.7.0 Use wc_format_price_range instead.
* @param string $from String or float to wrap with 'from' text
* @param mixed $to String or float to wrap with 'to' text
* @return string
*/
public function get_price_html_from_to( $from, $to ) {
_deprecated_function( 'WC_Product::get_price_html_from_to', '2.7', 'wc_format_price_range' );
return apply_filters( 'woocommerce_get_price_html_from_to', wc_format_price_range( $from, $to ), $from, $to, $this );
}
/**
* Get the suffix to display after prices > 0.
*
* @deprecated 2.7.0 Use wc_get_price_suffix instead.
* @param string $price to calculate, left blank to just use get_price()
* @param integer $qty passed on to get_price_including_tax() or get_price_excluding_tax()
* @return string
*/
public function get_price_suffix( $price = '', $qty = 1 ) {
_deprecated_function( 'WC_Product::get_price_suffix', '2.7', 'wc_get_price_suffix' );
return wc_get_price_suffix( $this, $price, $qty );
}
/**
* Lists a table of attributes for the product page.
* @deprecated 2.7.0 Use wc_display_product_attributes instead.
*/
public function list_attributes() {
_deprecated_function( 'WC_Product::list_attributes', '2.7', 'wc_display_product_attributes' );
wc_display_product_attributes( $this );
}
/**
* Returns the availability of the product.
*
* If stock management is enabled at global and product level, a stock message
* will be shown. e.g. In stock, In stock x10, Out of stock.
*
* If stock management is disabled at global or product level, out of stock
* will be shown when needed, but in stock will be hidden from view.
*
* This can all be changed through use of the woocommerce_get_availability filter.
*
* @return string
*/
public function get_availability() {
return apply_filters( 'woocommerce_get_availability', array(
'availability' => $this->get_availability_text(),
'class' => $this->get_availability_class(),
), $this );
}
/**
* Get availability text based on stock status.
*
* @return string
*/
protected function get_availability_text() {
if ( ! $this->is_in_stock() ) {
$availability = __( 'Out of stock', 'woocommerce' );
} elseif ( $this->managing_stock() && $this->is_on_backorder( 1 ) ) {
$availability = $this->backorders_require_notification() ? __( 'Available on backorder', 'woocommerce' ) : __( 'In stock', 'woocommerce' );
} elseif ( $this->managing_stock() ) {
switch ( get_option( 'woocommerce_stock_format' ) ) {
case 'no_amount' :
$availability = __( 'In stock', 'woocommerce' );
break;
case 'low_amount' :
if ( $this->get_total_stock() <= get_option( 'woocommerce_notify_low_stock_amount' ) ) {
$availability = sprintf( __( 'Only %s left in stock', 'woocommerce' ), $this->get_total_stock() );
if ( $this->backorders_allowed() && $this->backorders_require_notification() ) {
$availability .= ' ' . __( '(also available on backorder)', 'woocommerce' );
}
} else {
$availability = __( 'In stock', 'woocommerce' );
}
break;
default :
$availability = sprintf( __( '%s in stock', 'woocommerce' ), $this->get_total_stock() );
if ( $this->backorders_allowed() && $this->backorders_require_notification() ) {
$availability .= ' ' . __( '(also available on backorder)', 'woocommerce' );
}
break;
}
} else {
$availability = '';
}
return apply_filters( 'woocommerce_get_availability_text', $availability, $this );
}
/**
* Get availability classname based on stock status.
*
* @return string
*/
protected function get_availability_class() {
if ( ! $this->is_in_stock() ) {
$class = 'out-of-stock';
} elseif ( $this->managing_stock() && $this->is_on_backorder( 1 ) && $this->backorders_require_notification() ) {
$class = 'available-on-backorder';
} else {
$class = 'in-stock';
}
return apply_filters( 'woocommerce_get_availability_class', $class, $this );
}
/**
* The product's type (simple, variable etc).

View File

@ -98,128 +98,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
}
}
/*
|--------------------------------------------------------------------------
| Conditionals
|--------------------------------------------------------------------------
*/
/**
* Check if a product supports a given feature.
*
* Product classes should override this to declare support (or lack of support) for a feature.
*
* @param string $feature string The name of a feature to test support for.
* @return bool True if the product supports the feature, false otherwise.
* @since 2.5.0
*/
public function supports( $feature ) {
return apply_filters( 'woocommerce_product_supports', in_array( $feature, $this->supports ) ? true : false, $feature, $this );
}
/**
* Returns whether or not the product post exists.
*
* @return bool
*/
public function exists() {
return false !== $this->get_status();
}
/**
* Checks the product type.
*
* Backwards compat with downloadable/virtual.
*
* @param string $type Array or string of types
* @return bool
*/
public function is_type( $type ) {
return ( $this->get_type() === $type || ( is_array( $type ) && in_array( $this->get_type(), $type ) ) );
}
/**
* Checks if a product is downloadable.
*
* @return bool
*/
public function is_downloadable() {
return apply_filters( 'woocommerce_is_downloadable', true === $this->data['downloadable'] , $this );
}
/**
* Checks if a product is virtual (has no shipping).
*
* @return bool
*/
public function is_virtual() {
return apply_filters( 'woocommerce_is_virtual', true === $this->data['virtual'], $this );
}
/**
* Returns whether or not the product is featured.
*
* @return bool
*/
public function is_featured() {
return true === $this->get_featured();
}
/**
* Check if a product is sold individually (no quantities).
*
* @return bool
*/
public function is_sold_individually() {
return apply_filters( 'woocommerce_is_sold_individually', true === $this->get_sold_individually(), $this );
}
/**
* Returns whether or not the product is visible in the catalog.
*
* @return bool
*/
public function is_visible() {
$visible = 'visible' === $this->get_catalog_visibility() || ( is_search() && 'search' === $this->get_catalog_visibility() ) || ( ! is_search() && 'catalog' === $this->get_catalog_visibility() );
if ( 'publish' !== $this->get_status() && ! current_user_can( 'edit_post', $this->get_id() ) ) {
$visible = false;
}
if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $this->is_in_stock() ) {
$visible = false;
}
return apply_filters( 'woocommerce_product_is_visible', $visible, $this->get_id() );
}
/**
* Returns false if the product cannot be bought.
*
* @return bool
*/
public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', $this->exists() && ( 'publish' === $this->get_status() || current_user_can( 'edit_post', $this->get_id() ) ) && '' !== $this->get_price(), $this );
}
/**
* Returns whether or not the product has dimensions set.
*
* @return bool
*/
public function has_dimensions() {
return $this->get_length() || $this->get_height() || $this->get_width();
}
/**
* Returns whether or not the product has weight set.
*
* @return bool
*/
public function has_weight() {
return $this->get_weight() ? true : false;
}
/*
|--------------------------------------------------------------------------
| Getters
@ -1021,7 +899,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @param array $terms_id List of terms IDs.
*/
public function set_categories( $terms_id ) {
$this->save_taxonomy_terms( $terms_id, 'cat' );
//$this->save_taxonomy_terms( $terms_id, 'cat' );
}
/**
@ -1031,7 +909,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @param array $terms_id List of terms IDs.
*/
public function set_tags( $terms_id ) {
$this->save_taxonomy_terms( $terms_id, 'tag' );
//$this->save_taxonomy_terms( $terms_id, 'tag' );
}
/*
@ -1209,22 +1087,289 @@ class WC_Product extends WC_Abstract_Legacy_Product {
update_post_meta( $id, '_default_attributes', $this->get_default_attributes() );
}
/*
|--------------------------------------------------------------------------
| Conditionals
|--------------------------------------------------------------------------
*/
/**
* Check if a product supports a given feature.
*
* Product classes should override this to declare support (or lack of support) for a feature.
*
* @param string $feature string The name of a feature to test support for.
* @return bool True if the product supports the feature, false otherwise.
* @since 2.5.0
*/
public function supports( $feature ) {
return apply_filters( 'woocommerce_product_supports', in_array( $feature, $this->supports ) ? true : false, $feature, $this );
}
/**
* Returns whether or not the product post exists.
*
* @return bool
*/
public function exists() {
return false !== $this->get_status();
}
/**
* Checks the product type.
*
* Backwards compat with downloadable/virtual.
*
* @param string $type Array or string of types
* @return bool
*/
public function is_type( $type ) {
return ( $this->get_type() === $type || ( is_array( $type ) && in_array( $this->get_type(), $type ) ) );
}
/**
* Checks if a product is downloadable.
*
* @return bool
*/
public function is_downloadable() {
return apply_filters( 'woocommerce_is_downloadable', true === $this->data['downloadable'] , $this );
}
/**
* Checks if a product is virtual (has no shipping).
*
* @return bool
*/
public function is_virtual() {
return apply_filters( 'woocommerce_is_virtual', true === $this->data['virtual'], $this );
}
/**
* Returns whether or not the product is featured.
*
* @return bool
*/
public function is_featured() {
return true === $this->get_featured();
}
/**
* Check if a product is sold individually (no quantities).
*
* @return bool
*/
public function is_sold_individually() {
return apply_filters( 'woocommerce_is_sold_individually', true === $this->get_sold_individually(), $this );
}
/**
* Returns whether or not the product is visible in the catalog.
*
* @return bool
*/
public function is_visible() {
$visible = 'visible' === $this->get_catalog_visibility() || ( is_search() && 'search' === $this->get_catalog_visibility() ) || ( ! is_search() && 'catalog' === $this->get_catalog_visibility() );
if ( 'publish' !== $this->get_status() && ! current_user_can( 'edit_post', $this->get_id() ) ) {
$visible = false;
}
if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $this->is_in_stock() ) {
$visible = false;
}
return apply_filters( 'woocommerce_product_is_visible', $visible, $this->get_id() );
}
/**
* Returns false if the product cannot be bought.
*
* @return bool
*/
public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', $this->exists() && ( 'publish' === $this->get_status() || current_user_can( 'edit_post', $this->get_id() ) ) && '' !== $this->get_price(), $this );
}
/**
* Returns whether or not the product is on sale.
*
* @return bool
*/
public function is_on_sale() {
return apply_filters( 'woocommerce_product_is_on_sale', ( $this->get_sale_price() !== $this->get_regular_price() && $this->get_sale_price() === $this->get_price() ), $this );
}
/**
* Returns whether or not the product has dimensions set.
*
* @return bool
*/
public function has_dimensions() {
return $this->get_length() || $this->get_height() || $this->get_width();
}
/**
* Returns whether or not the product has weight set.
*
* @return bool
*/
public function has_weight() {
return $this->get_weight() ? true : false;
}
/**
* Returns whether or not the product is in stock.
*
* @return bool
*/
public function is_in_stock() {
return apply_filters( 'woocommerce_product_is_in_stock', 'instock' === $this->get_stock_status(), $this );
}
/**
* Checks if a product needs shipping.
*
* @return bool
*/
public function needs_shipping() {
return apply_filters( 'woocommerce_product_needs_shipping', ! $this->is_virtual(), $this );
}
/**
* Returns whether or not the product is taxable.
*
* @return bool
*/
public function is_taxable() {
return apply_filters( 'woocommerce_product_is_taxable', $this->get_tax_status() === 'taxable' && wc_tax_enabled(), $this );
}
/**
* Returns whether or not the product shipping is taxable.
*
* @return bool
*/
public function is_shipping_taxable() {
return $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping';
}
/**
* Returns whether or not the product is stock managed.
*
* @return bool
*/
public function managing_stock() {
return $this->get_manage_stock() && 'yes' === get_option( 'woocommerce_manage_stock' );
}
/**
* Returns whether or not the product can be backordered.
*
* @return bool
*/
public function backorders_allowed() {
return apply_filters( 'woocommerce_product_backorders_allowed', ( 'yes' === $this->get_backorders() || 'notify' === $this->get_backorders() ), $this->get_id(), $this );
}
/**
* Returns whether or not the product needs to notify the customer on backorder.
*
* @return bool
*/
public function backorders_require_notification() {
return apply_filters( 'woocommerce_product_backorders_require_notification', ( $this->managing_stock() && 'notify' === $this->get_backorders() ), $this );
}
/**
* Check if a product is on backorder.
*
* @param int $qty_in_cart (default: 0)
* @return bool
*/
public function is_on_backorder( $qty_in_cart = 0 ) {
return $this->managing_stock() && $this->backorders_allowed() && ( $this->get_total_stock() - $qty_in_cart ) < 0 ? true : false;
}
/**
* Returns whether or not the product has enough stock for the order.
*
* @param mixed $quantity
* @return bool
*/
public function has_enough_stock( $quantity ) {
return ! $this->managing_stock() || $this->backorders_allowed() || $this->get_stock_quantity() >= $quantity ? true : false;
}
/*
|--------------------------------------------------------------------------
| Non-CRUD Getters
|--------------------------------------------------------------------------
*/
/**
* Get the add to url used mainly in loops.
*
* @return string
*/
public function add_to_cart_url() {
return apply_filters( 'woocommerce_product_add_to_cart_url', get_permalink( $this->get_id() ), $this );
}
/**
* Get the add to cart button text for the single page.
*
* @return string
*/
public function single_add_to_cart_text() {
return apply_filters( 'woocommerce_product_single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $this );
}
/**
* Get the add to cart button text.
*
* @return string
*/
public function add_to_cart_text() {
return apply_filters( 'woocommerce_product_add_to_cart_text', __( 'Read more', 'woocommerce' ), $this );
}
/**
* Gets the main product image ID.
*
* @return int
*/
public function get_image_id() {
if ( has_post_thumbnail( $this->get_id() ) ) {
$image_id = get_post_thumbnail_id( $this->get_id() );
} elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {
$image_id = get_post_thumbnail_id( $parent_id );
} else {
$image_id = 0;
}
return $image_id;
}
/**
* Returns the main product image.
*
* @param string $size (default: 'shop_thumbnail')
* @param array $attr
* @param bool True to return $placeholder if no image is found, or false to return an empty string.
* @return string
*/
public function get_image( $size = 'shop_thumbnail', $attr = array(), $placeholder = true ) {
if ( has_post_thumbnail( $this->get_id() ) ) {
$image = get_the_post_thumbnail( $this->get_id(), $size, $attr );
} elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {
$image = get_the_post_thumbnail( $parent_id, $size, $attr );
} elseif ( $placeholder ) {
$image = wc_placeholder_img( $size );
} else {
$image = '';
}
return str_replace( array( 'https://', 'http://' ), '//', $image );
}
@ -1457,14 +1602,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
/**
* Checks if a product needs shipping.
*
* @return bool
*/
public function needs_shipping() {
return apply_filters( 'woocommerce_product_needs_shipping', $this->is_virtual() ? false : true, $this );
}
@ -1488,198 +1626,10 @@ class WC_Product extends WC_Abstract_Legacy_Product {
/**
* Returns whether or not the product is taxable.
*
* @return bool
*/
public function is_taxable() {
$taxable = $this->get_tax_status() === 'taxable' && wc_tax_enabled() ? true : false;
return apply_filters( 'woocommerce_product_is_taxable', $taxable, $this );
}
/**
* Returns whether or not the product shipping is taxable.
*
* @return bool
*/
public function is_shipping_taxable() {
return $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping' ? true : false;
}
/**
* Get the add to url used mainly in loops.
*
* @return string
*/
public function add_to_cart_url() {
return apply_filters( 'woocommerce_product_add_to_cart_url', get_permalink( $this->get_id() ), $this );
}
/**
* Get the add to cart button text for the single page.
*
* @return string
*/
public function single_add_to_cart_text() {
return apply_filters( 'woocommerce_product_single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $this );
}
/**
* Get the add to cart button text.
*
* @return string
*/
public function add_to_cart_text() {
return apply_filters( 'woocommerce_product_add_to_cart_text', __( 'Read more', 'woocommerce' ), $this );
}
/**
* Returns whether or not the product is stock managed.
*
* @return bool
*/
public function managing_stock() {
$managing_stock = 'no' === $this->get_manage_stock() || 'yes' !== get_option( 'woocommerce_manage_stock' );
return ! $managing_stock;
}
/**
* Returns whether or not the product is in stock.
*
* @return bool
*/
public function is_in_stock() {
return apply_filters( 'woocommerce_product_is_in_stock', ( 'instock' === $this->stock_status ), $this );
}
/**
* Returns whether or not the product can be backordered.
*
* @return bool
*/
public function backorders_allowed() {
return apply_filters( 'woocommerce_product_backorders_allowed', ( 'yes' === $this->get_backorders() || 'notify' === $this->get_backorders() ), $this->get_id(), $this );
}
/**
* Returns whether or not the product needs to notify the customer on backorder.
*
* @return bool
*/
public function backorders_require_notification() {
return apply_filters( 'woocommerce_product_backorders_require_notification', ( $this->managing_stock() && 'notify' === $this->backorders ), $this );
}
/**
* Check if a product is on backorder.
*
* @param int $qty_in_cart (default: 0)
* @return bool
*/
public function is_on_backorder( $qty_in_cart = 0 ) {
return $this->managing_stock() && $this->backorders_allowed() && ( $this->get_total_stock() - $qty_in_cart ) < 0 ? true : false;
}
/**
* Returns whether or not the product has enough stock for the order.
*
* @param mixed $quantity
* @return bool
*/
public function has_enough_stock( $quantity ) {
return ! $this->managing_stock() || $this->backorders_allowed() || $this->get_stock_quantity() >= $quantity ? true : false;
}
/**
* Returns the availability of the product.
*
* If stock management is enabled at global and product level, a stock message
* will be shown. e.g. In stock, In stock x10, Out of stock.
*
* If stock management is disabled at global or product level, out of stock
* will be shown when needed, but in stock will be hidden from view.
*
* This can all be changed through use of the woocommerce_get_availability filter.
*
* @return string
*/
public function get_availability() {
return apply_filters( 'woocommerce_get_availability', array(
'availability' => $this->get_availability_text(),
'class' => $this->get_availability_class(),
), $this );
}
/**
* Get availability text based on stock status.
*
* @return string
*/
protected function get_availability_text() {
if ( ! $this->is_in_stock() ) {
$availability = __( 'Out of stock', 'woocommerce' );
} elseif ( $this->managing_stock() && $this->is_on_backorder( 1 ) ) {
$availability = $this->backorders_require_notification() ? __( 'Available on backorder', 'woocommerce' ) : __( 'In stock', 'woocommerce' );
} elseif ( $this->managing_stock() ) {
switch ( get_option( 'woocommerce_stock_format' ) ) {
case 'no_amount' :
$availability = __( 'In stock', 'woocommerce' );
break;
case 'low_amount' :
if ( $this->get_total_stock() <= get_option( 'woocommerce_notify_low_stock_amount' ) ) {
$availability = sprintf( __( 'Only %s left in stock', 'woocommerce' ), $this->get_total_stock() );
if ( $this->backorders_allowed() && $this->backorders_require_notification() ) {
$availability .= ' ' . __( '(also available on backorder)', 'woocommerce' );
}
} else {
$availability = __( 'In stock', 'woocommerce' );
}
break;
default :
$availability = sprintf( __( '%s in stock', 'woocommerce' ), $this->get_total_stock() );
if ( $this->backorders_allowed() && $this->backorders_require_notification() ) {
$availability .= ' ' . __( '(also available on backorder)', 'woocommerce' );
}
break;
}
} else {
$availability = '';
}
return apply_filters( 'woocommerce_get_availability_text', $availability, $this );
}
/**
* Get availability classname based on stock status.
*
* @return string
*/
protected function get_availability_class() {
if ( ! $this->is_in_stock() ) {
$class = 'out-of-stock';
} elseif ( $this->managing_stock() && $this->is_on_backorder( 1 ) && $this->backorders_require_notification() ) {
$class = 'available-on-backorder';
} else {
$class = 'in-stock';
}
return apply_filters( 'woocommerce_get_availability_class', $class, $this );
}
/**
* Returns whether or not the product is on sale.
*
* @return bool
*/
public function is_on_sale() {
return apply_filters( 'woocommerce_product_is_on_sale', ( $this->get_sale_price() !== $this->get_regular_price() && $this->get_sale_price() === $this->get_price() ), $this );
}
@ -1811,118 +1761,25 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return $display_price;
}
/**
* Get the suffix to display after prices > 0.
*
* @param string $price to calculate, left blank to just use get_price()
* @param integer $qty passed on to get_price_including_tax() or get_price_excluding_tax()
* @return string
*/
public function get_price_suffix( $price = '', $qty = 1 ) {
if ( '' === $price ) {
$price = $this->get_price();
}
$price_display_suffix = get_option( 'woocommerce_price_display_suffix' );
$woocommerce_calc_taxes = get_option( 'woocommerce_calc_taxes', 'no' );
if ( $price_display_suffix && 'yes' === $woocommerce_calc_taxes ) {
$price_display_suffix = ' <small class="woocommerce-price-suffix">' . $price_display_suffix . '</small>';
$find = array(
'{price_including_tax}',
'{price_excluding_tax}',
);
$replace = array(
wc_price( $this->get_price_including_tax( $qty, $price ) ),
wc_price( $this->get_price_excluding_tax( $qty, $price ) ),
);
$price_display_suffix = str_replace( $find, $replace, $price_display_suffix );
} else {
$price_display_suffix = '';
}
return apply_filters( 'woocommerce_get_price_suffix', $price_display_suffix, $this );
}
/**
* Returns the price in html format.
*
* @param string $price (default: '')
* @return string
*/
public function get_price_html( $price = '' ) {
public function get_price_html( $deprecated = '' ) {
if ( '' === $this->get_price() ) {
return apply_filters( 'woocommerce_empty_price_html', '', $this );
}
$display_price = $this->get_display_price();
$display_regular_price = $this->get_display_price( $this->get_regular_price() );
if ( $this->get_price() > 0 ) {
if ( $this->is_on_sale() && $this->get_regular_price() ) {
$price .= $this->get_price_html_from_to( $display_regular_price, $display_price ) . $this->get_price_suffix();
$price = apply_filters( 'woocommerce_sale_price_html', $price, $this );
} else {
$price .= wc_price( $display_price ) . $this->get_price_suffix();
$price = apply_filters( 'woocommerce_price_html', $price, $this );
}
} elseif ( $this->get_price() === '' ) {
$price = apply_filters( 'woocommerce_empty_price_html', '', $this );
} elseif ( $this->get_price() == 0 ) {
if ( $this->is_on_sale() && $this->get_regular_price() ) {
$price .= $this->get_price_html_from_to( $display_regular_price, __( 'Free!', 'woocommerce' ) );
$price = apply_filters( 'woocommerce_free_sale_price_html', $price, $this );
} else {
$price = '<span class="amount">' . __( 'Free!', 'woocommerce' ) . '</span>';
$price = apply_filters( 'woocommerce_free_price_html', $price, $this );
}
if ( $this->is_on_sale() ) {
$price = wc_format_price_range( $product->get_display_price( $product->get_regular_price() ), $product->get_display_price() ) . wc_get_price_suffix( $this );
} else {
$price = wc_price( $product->get_display_price() ) . wc_get_price_suffix( $this );
}
return apply_filters( 'woocommerce_get_price_html', $price, $this );
}
/**
* Functions for getting parts of a price, in html, used by get_price_html.
*
* @return string
*/
public function get_price_html_from_text() {
$from = '<span class="from">' . _x( 'From:', 'min_price', 'woocommerce' ) . ' </span>';
return apply_filters( 'woocommerce_get_price_html_from_text', $from, $this );
}
/**
* Functions for getting parts of a price, in html, used by get_price_html.
*
* @param string $from String or float to wrap with 'from' text
* @param mixed $to String or float to wrap with 'to' text
* @return string
*/
public function get_price_html_from_to( $from, $to ) {
$price = '<del>' . ( ( is_numeric( $from ) ) ? wc_price( $from ) : $from ) . '</del> <ins>' . ( ( is_numeric( $to ) ) ? wc_price( $to ) : $to ) . '</ins>';
return apply_filters( 'woocommerce_get_price_html_from_to', $price, $from, $to, $this );
}
@ -2066,53 +1923,9 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this );
}
/**
* Lists a table of attributes for the product page.
*/
public function list_attributes() {
wc_get_template( 'single-product/product-attributes.php', array(
'product' => $this,
) );
}
/**
* Gets the main product image ID.
*
* @return int
*/
public function get_image_id() {
if ( has_post_thumbnail( $this->get_id() ) ) {
$image_id = get_post_thumbnail_id( $this->get_id() );
} elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {
$image_id = get_post_thumbnail_id( $parent_id );
} else {
$image_id = 0;
}
return $image_id;
}
/**
* Returns the main product image.
*
* @param string $size (default: 'shop_thumbnail')
* @param array $attr
* @param bool True to return $placeholder if no image is found, or false to return an empty string.
* @return string
*/
public function get_image( $size = 'shop_thumbnail', $attr = array(), $placeholder = true ) {
if ( has_post_thumbnail( $this->get_id() ) ) {
$image = get_the_post_thumbnail( $this->get_id(), $size, $attr );
} elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {
$image = get_the_post_thumbnail( $parent_id, $size, $attr );
} elseif ( $placeholder ) {
$image = wc_placeholder_img( $size );
} else {
$image = '';
}
return str_replace( array( 'https://', 'http://' ), '//', $image );
}
/**
* Get product name with SKU or ID. Used within admin.
@ -2128,18 +1941,4 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return sprintf( '%s &ndash; %s', $identifier, $this->get_title() );
}
/**
* Save taxonomy terms.
*
* @since 2.7.0
* @param array $terms_id Terms ID.
* @param string $taxonomy Taxonomy.
* @return array|WP_Error
*/
protected function save_taxonomy_terms( $terms_id, $taxonomy = 'cat' ) {
$terms_id = array_unique( array_map( 'intval', $terms_id ) );
return wp_set_object_terms( $this->get_id(), $terms_id, 'product_' . $taxonomy );
}
}

View File

@ -590,10 +590,6 @@ class WC_Product_Variable extends WC_Product {
$image = $image_link = $image_title = $image_alt = $image_srcset = $image_sizes = $image_caption = '';
}
$availability = $variation->get_availability();
$availability_html = empty( $availability['availability'] ) ? '' : '<p class="stock ' . esc_attr( $availability['class'] ) . '">' . wp_kses_post( $availability['availability'] ) . '</p>';
$availability_html = apply_filters( 'woocommerce_stock_html', $availability_html, $availability['availability'], $variation );
return apply_filters( 'woocommerce_available_variation', array(
'variation_id' => $variation->variation_id,
'variation_is_visible' => $variation->variation_is_visible(),
@ -610,7 +606,7 @@ class WC_Product_Variable extends WC_Product {
'image_srcset' => $image_srcset ? $image_srcset : '',
'image_sizes' => $image_sizes ? $image_sizes : '',
'price_html' => apply_filters( 'woocommerce_show_variation_price', $variation->get_price() === "" || $this->get_variation_price( 'min' ) !== $this->get_variation_price( 'max' ), $this, $variation ) ? '<span class="price">' . $variation->get_price_html() . '</span>' : '',
'availability_html' => $availability_html,
'availability_html' => wc_get_product_stock_html( $variation ),
'sku' => $variation->get_sku(),
'weight' => $variation->get_weight() ? $variation->get_weight() . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ) : '',
'dimensions' => $variation->get_dimensions(),

View File

@ -873,3 +873,44 @@ if ( ! function_exists( 'wc_make_numeric_postcode' ) ) {
return $numeric_postcode;
}
}
/**
* Format the stock amount ready for display based on settings.
* @since 2.7.0
* @param int $stock_amount
* @param boolean $show_backorder_notification
* @return string
*/
function wc_format_stock_for_display( $stock_amount, $show_backorder_notification = false ) {
$display = __( 'In stock', 'woocommerce' );
switch ( get_option( 'woocommerce_stock_format' ) ) {
case 'low_amount' :
if ( $stock_amount <= get_option( 'woocommerce_notify_low_stock_amount' ) ) {
$display = sprintf( __( 'Only %s left in stock', 'woocommerce' ), $stock_amount );
}
break;
case '' :
$display = sprintf( __( '%s in stock', 'woocommerce' ), $stock_amount );
break;
}
if ( $show_backorder_notification ) {
$display .= ' ' . __( '(can be backordered)', 'woocommerce' );
}
return $display;
}
/**
* Format a price range for display.
* @since 2.7.0
* @param string $from
* @param string $to
* @return string
*/
function wc_format_price_range( $from, $to ) {
$price = '<del>' . ( ( is_numeric( $from ) ) ? wc_price( $from ) : $from ) . '</del> <ins>' . ( ( is_numeric( $to ) ) ? wc_price( $to ) : $to ) . '</ins>';
return apply_filters( 'woocommerce_format_price_range', $price, $from, $to );
}

View File

@ -2453,3 +2453,61 @@ if ( ! function_exists( 'wc_display_item_downloads' ) ) {
}
}
}
/**
* Outputs a list of product attributes.
* @since 2.7.0
* @param WC_Product $product
*/
function wc_display_product_attributes( $product ) {
wc_get_template( 'single-product/product-attributes.php', array(
'product' => $product,
) );
}
/**
* Get HTML to show product stock.
* @since 2.7.0
* @param WC_Product $product
* @return string
*/
function wc_get_product_stock_html( $product ) {
ob_start();
wc_get_template( 'single-product/stock.php', array(
'product' => $product,
) );
return apply_filters( 'woocommerce_get_product_stock_html', ob_get_clean(), $product ); // @todo map old woocommerce_stock_html filter to this
}
/**
* Get the price suffix for a product if needed.
* @since 2.7.0
* @param WC_Product $product
* @param string $price
* @param integer $qty
* @return string
*/
function wc_get_price_suffix( $product, $price = '', $qty = 1 ) {
if ( ( $price_display_suffix = get_option( 'woocommerce_price_display_suffix' ) ) && wc_tax_enabled() ) {
$price = '' === $price ? $product->get_price() : $price;
$price_display_suffix = ' <small class="woocommerce-price-suffix">' . wp_kses_post( $price_display_suffix ) . '</small>';
$find = array(
'{price_including_tax}',
'{price_excluding_tax}',
);
$replace = array(
wc_price( $product->get_price_including_tax( $qty, $price ) ),
wc_price( $product->get_price_excluding_tax( $qty, $price ) ),
);
$price_display_suffix = str_replace( $find, $replace, $price_display_suffix );
} else {
$price_display_suffix = '';
}
return apply_filters( 'woocommerce_get_price_suffix', $price_display_suffix, $product );
}

View File

@ -70,11 +70,7 @@ do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<td class="price">
<?php
echo $product->get_price_html();
if ( $availability = $product->get_availability() ) {
$availability_html = empty( $availability['availability'] ) ? '' : '<p class="stock ' . esc_attr( $availability['class'] ) . '">' . esc_html( $availability['availability'] ) . '</p>';
echo apply_filters( 'woocommerce_stock_html', $availability_html, $availability['availability'], $product );
}
echo wc_get_product_stock_html( $product );
?>
</td>
</tr>

View File

@ -26,17 +26,9 @@ if ( ! $product->is_purchasable() ) {
return;
}
?>
echo wc_get_product_stock_html( $product );
<?php
// Availability
$availability = $product->get_availability();
$availability_html = empty( $availability['availability'] ) ? '' : '<p class="stock ' . esc_attr( $availability['class'] ) . '">' . esc_html( $availability['availability'] ) . '</p>';
echo apply_filters( 'woocommerce_stock_html', $availability_html, $availability['availability'], $product );
?>
<?php if ( $product->is_in_stock() ) : ?>
if ( $product->is_in_stock() ) : ?>
<?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>

View File

@ -0,0 +1,35 @@
<?php
/**
* Single Product stock.
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/stock.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.7.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! $product->is_in_stock() ) : ?>
<p class="stock out-of-stock"><?php _e( 'Out of stock', 'woocommerce' ); ?></p>
<?php elseif ( $product->managing_stock() && $product->is_on_backorder( 1 ) ) : ?>
<p class="stock available-on-backorder"><?php _e( 'Available on backorder', 'woocommerce' ); ?></p>
<?php elseif ( $product->managing_stock() ) : ?>
<p class="stock in-stock"><?php echo wp_kses_post( wc_format_stock_for_display( $product->get_total_stock(), $product->backorders_allowed() && $product->backorders_require_notification() ) ); ?></p>
<?php endif; ?>

View File

@ -13,7 +13,7 @@
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.0.0
* @version 2.7.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -30,4 +30,4 @@ $heading = esc_html( apply_filters( 'woocommerce_product_additional_information_
<h2><?php echo $heading; ?></h2>
<?php endif; ?>
<?php $product->list_attributes(); ?>
<?php wc_display_product_attributes( $product ); ?>