[Product CRUD] Abstract todos (#12305)
* Get dimensions and weights, with soft deprecation * Product attributes * Ratings * Fix read method * Downloads * Feedback
This commit is contained in:
parent
1fb8479358
commit
9a6136fcf8
File diff suppressed because one or more lines are too long
|
@ -1024,8 +1024,8 @@ p.demo_store,
|
|||
}
|
||||
}
|
||||
|
||||
.alt td,
|
||||
.alt th {
|
||||
tr:nth-child(even) td,
|
||||
tr:nth-child(even) th {
|
||||
background: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -661,4 +661,61 @@ abstract class WC_Abstract_Legacy_Product extends WC_Data {
|
|||
_deprecated_function( 'WC_Product::get_matching_variation', '2.7', 'wc_find_matching_product_variation' );
|
||||
return wc_find_matching_product_variation( $this, $match_attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not we are showing dimensions on the product page.
|
||||
* @deprecated 2.7.0 Unused.
|
||||
* @return bool
|
||||
*/
|
||||
public function enable_dimensions_display() {
|
||||
_deprecated_function( 'WC_Product::enable_dimensions_display', '2.7' );
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() || $this->child_has_weight() || $this->child_has_dimensions() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product rating in html format.
|
||||
*
|
||||
* @deprecated 2.7.0
|
||||
* @param string $rating (default: '')
|
||||
* @return string
|
||||
*/
|
||||
public function get_rating_html( $rating = null ) {
|
||||
_deprecated_function( 'WC_Product::get_rating_html', '2.7', 'wc_get_rating_html' );
|
||||
return wc_get_rating_html( $rating );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync product rating. Can be called statically.
|
||||
*
|
||||
* @deprecated 2.7.0
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function sync_average_rating( $post_id ) {
|
||||
_deprecated_function( 'WC_Product::sync_average_rating', '2.7', 'WC_Comments::get_average_rating_for_product or leave to CRUD.' );
|
||||
$average = WC_Comments::get_average_rating_for_product( wc_get_product( $post_id ) );
|
||||
update_post_meta( $post_id, '_wc_average_rating', $average );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync product rating count. Can be called statically.
|
||||
*
|
||||
* @deprecated 2.7.0
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function sync_rating_count( $post_id ) {
|
||||
_deprecated_function( 'WC_Product::sync_rating_count', '2.7', 'WC_Comments::get_rating_counts_for_product or leave to CRUD.' );
|
||||
$counts = WC_Comments::get_rating_counts_for_product( wc_get_product( $post_id ) );
|
||||
update_post_meta( $post_id, '_wc_rating_count', $counts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as get_downloads in CRUD.
|
||||
*
|
||||
* @deprecated 2.7.0
|
||||
* @return array
|
||||
*/
|
||||
public function get_files() {
|
||||
wc_soft_deprecated_function( 'WC_Product::get_files', '2.7', '2.8', 'WC_Product::get_downloads' );
|
||||
return $this->get_downloads();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,9 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
'gallery_image_ids' => array(),
|
||||
'download_limit' => -1,
|
||||
'download_expiry' => -1,
|
||||
'rating_counts' => array(),
|
||||
'average_rating' => 0,
|
||||
'review_count' => 0,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -473,6 +476,24 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return $this->get_prop( 'height', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted dimensions.
|
||||
*
|
||||
* @param $formatted True by default for legacy support - will be false/not set in future versions to return the array only. Use wc_format_dimensions for formatted versions instead.
|
||||
* @return string|array
|
||||
*/
|
||||
public function get_dimensions( $formatted = true ) {
|
||||
if ( $formatted ) {
|
||||
wc_soft_deprecated_argument( 'WC_Product::get_dimensions', '2.7', '2.8', 'By default, get_dimensions has an argument set to true so that HTML is returned. This is to support the legacy version of the method. To get HTML dimensions, instead use wc_format_dimensions() function. Pass false to this method to return an array of dimensions. This will be the new default behavior in future versions.' );
|
||||
return apply_filters( 'woocommerce_product_dimensions', wc_format_dimensions( $this->get_dimensions( false ) ), $this );
|
||||
}
|
||||
return array(
|
||||
'length' => $this->get_length(),
|
||||
'width' => $this->get_width(),
|
||||
'height' => $this->get_height(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upsel IDs.
|
||||
*
|
||||
|
@ -669,6 +690,33 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return $this->get_prop( 'image_id', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rating count.
|
||||
* @param string $context
|
||||
* @return array of counts
|
||||
*/
|
||||
public function get_rating_counts( $context = 'view' ) {
|
||||
return $this->get_prop( 'rating_counts', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get average rating.
|
||||
* @param string $context
|
||||
* @return float
|
||||
*/
|
||||
public function get_average_rating( $context = 'view' ) {
|
||||
return $this->get_prop( 'average_rating', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get review count.
|
||||
* @param string $context
|
||||
* @return int
|
||||
*/
|
||||
public function get_review_count( $context = 'view' ) {
|
||||
return $this->get_prop( 'review_count', $context );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Setters
|
||||
|
@ -1124,65 +1172,42 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* Set downloads.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param $raw_downloads array of arrays with download data (name/file)
|
||||
* @param $downloads_array array of WC_Product_Download objects or arrays.
|
||||
*/
|
||||
public function set_downloads( $raw_downloads ) {
|
||||
$downloads = array();
|
||||
$errors = array();
|
||||
$allowed_file_types = apply_filters( 'woocommerce_downloadable_file_allowed_mime_types', get_allowed_mime_types() );
|
||||
public function set_downloads( $downloads_array ) {
|
||||
$downloads = array();
|
||||
$errors = array();
|
||||
|
||||
foreach ( $raw_downloads as $raw_download ) {
|
||||
$file_name = wc_clean( $raw_download['name'] );
|
||||
|
||||
// Find type and file URL
|
||||
if ( 0 === strpos( $raw_download['file'], 'http' ) ) {
|
||||
$file_is = 'absolute';
|
||||
$file_url = esc_url_raw( $raw_download['file'] );
|
||||
} elseif ( '[' === substr( $raw_download['file'], 0, 1 ) && ']' === substr( $raw_download['file'], -1 ) ) {
|
||||
$file_is = 'shortcode';
|
||||
$file_url = wc_clean( $raw_download['file'] );
|
||||
foreach ( $downloads_array as $download ) {
|
||||
if ( is_a( $download, 'WC_Product_Download' ) ) {
|
||||
$download_object = $download;
|
||||
} else {
|
||||
$file_is = 'relative';
|
||||
$file_url = wc_clean( $raw_download['file'] );
|
||||
$download_object = new WC_Product_Download();
|
||||
$download_object->set_id( md5( $download['file'] ) );
|
||||
$download_object->set_name( $download['name'] );
|
||||
$download_object->set_file( $download['file'] );
|
||||
}
|
||||
|
||||
$file_name = wc_clean( $raw_download['name'] );
|
||||
|
||||
// Validate the file extension
|
||||
if ( in_array( $file_is, array( 'absolute', 'relative' ) ) ) {
|
||||
$file_type = wp_check_filetype( strtok( $file_url, '?' ), $allowed_file_types );
|
||||
$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 ) ) {
|
||||
$errors[] = sprintf( __( 'The downloadable file %1$s cannot be used as it does not have an allowed file type. Allowed types include: %2$s', 'woocommerce' ), '<code>' . basename( $file_url ) . '</code>', '<code>' . implode( ', ', array_keys( $allowed_file_types ) ) . '</code>' );
|
||||
continue;
|
||||
}
|
||||
if ( ! $download_object->is_allowed_filetype() ) {
|
||||
$errors[] = sprintf( __( 'The downloadable file %1$s cannot be used as it does not have an allowed file type. Allowed types include: %2$s', 'woocommerce' ), '<code>' . basename( $download_object->get_file() ) . '</code>', '<code>' . implode( ', ', array_keys( $download_object->get_allowed_mime_types() ) ) . '</code>' );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validate the file exists.
|
||||
if ( 'relative' === $file_is ) {
|
||||
$_file_url = $file_url;
|
||||
if ( '..' === substr( $file_url, 0, 2 ) || '/' !== substr( $file_url, 0, 1 ) ) {
|
||||
$_file_url = realpath( ABSPATH . $file_url );
|
||||
}
|
||||
|
||||
if ( ! apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $_file_url ), $file_url ) ) {
|
||||
$errors[] = sprintf( __( 'The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), '<code>' . $file_url . '</code>' );
|
||||
continue;
|
||||
}
|
||||
if ( ! $download_object->file_exists() ) {
|
||||
$errors[] = sprintf( __( 'The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), '<code>' . $download_object->get_file() . '</code>' );
|
||||
continue;
|
||||
}
|
||||
|
||||
$downloads[ md5( $file_url ) ] = array(
|
||||
'name' => $file_name,
|
||||
'file' => $file_url,
|
||||
);
|
||||
$downloads[ $download_object->get_id() ] = $download_object;
|
||||
}
|
||||
|
||||
$this->set_prop( 'downloads', $downloads );
|
||||
|
||||
if ( $errors ) {
|
||||
$this->error( 'product_invalid_download', $errors[0] );
|
||||
}
|
||||
|
||||
$this->set_prop( 'downloads', $downloads );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1225,6 +1250,30 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
$this->set_prop( 'image_id', $image_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rating counts. Read only.
|
||||
* @param array $counts
|
||||
*/
|
||||
protected function set_rating_counts( $counts ) {
|
||||
$this->set_prop( 'rating_counts', array_filter( array_map( 'absint', (array) $counts ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set average rating. Read only.
|
||||
* @param float $average
|
||||
*/
|
||||
protected function set_average_rating( $average ) {
|
||||
$this->set_prop( 'average_rating', wc_format_decimal( $average ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set review count. Read only.
|
||||
* @param int $count
|
||||
*/
|
||||
protected function set_review_count( $count ) {
|
||||
$this->set_prop( 'review_count', absint( $count ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| CRUD methods
|
||||
|
@ -1304,6 +1353,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
) );
|
||||
$this->read_meta_data();
|
||||
$this->read_attributes();
|
||||
$this->read_downloads();
|
||||
$this->read_product_data();
|
||||
|
||||
// Set object_read true once all data is read.
|
||||
|
@ -1316,7 +1366,26 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* @since 2.7.0
|
||||
*/
|
||||
protected function read_product_data() {
|
||||
$id = $this->get_id();
|
||||
$id = $this->get_id();
|
||||
$review_count = get_post_meta( $id, '_wc_review_count', true );
|
||||
$rating_counts = get_post_meta( $id, '_wc_rating_count', true );
|
||||
$average_rating = get_post_meta( $id, '_wc_average_rating', true );
|
||||
|
||||
if ( '' === $review_count ) {
|
||||
$review_count = WC_Comments::get_review_count_for_product( $this );
|
||||
}
|
||||
|
||||
if ( '' === $rating_counts ) {
|
||||
$rating_counts = WC_Comments::get_rating_counts_for_product( $this );
|
||||
}
|
||||
|
||||
if ( '' === $average_rating ) {
|
||||
$average_rating = WC_Comments::get_average_rating_for_product( $this );
|
||||
}
|
||||
|
||||
$this->set_average_rating( $average_rating );
|
||||
$this->set_rating_counts( $rating_counts );
|
||||
$this->set_review_count( $review_count );
|
||||
$this->set_props( array(
|
||||
'featured' => get_post_meta( $id, '_featured', true ),
|
||||
'catalog_visibility' => get_post_meta( $id, '_visibility', true ),
|
||||
|
@ -1347,7 +1416,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
'shipping_class_id' => current( $this->get_term_ids( 'product_shipping_class' ) ),
|
||||
'virtual' => get_post_meta( $id, '_virtual', true ),
|
||||
'downloadable' => get_post_meta( $id, '_downloadable', true ),
|
||||
'downloads' => array_filter( (array) get_post_meta( $id, '_downloadable_files', true ) ),
|
||||
'gallery_image_ids' => array_filter( explode( ',', get_post_meta( $id, '_product_image_gallery', true ) ) ),
|
||||
'download_limit' => get_post_meta( $id, '_download_limit', true ),
|
||||
'download_expiry' => get_post_meta( $id, '_download_expiry', true ),
|
||||
|
@ -1355,6 +1423,27 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read downloads from post meta.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
protected function read_downloads() {
|
||||
$meta_values = array_filter( (array) maybe_unserialize( get_post_meta( $this->get_id(), '_downloadable_files', true ) ) );
|
||||
|
||||
if ( $meta_values ) {
|
||||
$downloads = array();
|
||||
foreach ( $meta_values as $key => $value ) {
|
||||
$download = new WC_Product_Download();
|
||||
$download->set_id( $key );
|
||||
$download->set_name( $value['name'] ? $value['name'] : wc_get_filename_from_url( $value['file'] ) );
|
||||
$download->set_file( apply_filters( 'woocommerce_file_download_path', $value['file'], $this, $key ) );
|
||||
$downloads[] = $download;
|
||||
}
|
||||
$this->set_downloads( $downloads );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read attributes from post meta.
|
||||
*
|
||||
|
@ -1415,6 +1504,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
$this->update_post_meta();
|
||||
$this->update_terms();
|
||||
$this->update_attributes();
|
||||
$this->update_downloads();
|
||||
$this->save_meta_data();
|
||||
do_action( 'woocommerce_new_' . $this->post_type, $id );
|
||||
}
|
||||
|
@ -1440,6 +1530,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
$this->update_post_meta();
|
||||
$this->update_terms();
|
||||
$this->update_attributes();
|
||||
$this->update_downloads();
|
||||
$this->save_meta_data();
|
||||
do_action( 'woocommerce_update_' . $this->post_type, $this->get_id() );
|
||||
}
|
||||
|
@ -1578,8 +1669,10 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
'_downloadable_files' => 'downloads',
|
||||
'_stock' => 'stock_quantity',
|
||||
'_stock_status' => 'stock_status',
|
||||
'_wc_average_rating' => 'average_rating',
|
||||
'_wc_rating_count' => 'rating_counts',
|
||||
'_wc_review_count' => 'review_count',
|
||||
);
|
||||
|
||||
foreach ( $meta_key_to_props as $meta_key => $prop ) {
|
||||
if ( ! in_array( $prop, $changed_props ) ) {
|
||||
continue;
|
||||
|
@ -1596,6 +1689,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
case 'gallery_image_ids' :
|
||||
$updated = update_post_meta( $this->get_id(), $meta_key, implode( ',', $value ) );
|
||||
break;
|
||||
case 'downloads' :
|
||||
// grant permission to any newly added files on any existing orders for this product prior to saving.
|
||||
if ( $this->is_type( 'variation' ) ) {
|
||||
do_action( 'woocommerce_process_product_file_download_paths', $this->get_parent_id(), $this->get_id(), $value );
|
||||
} else {
|
||||
do_action( 'woocommerce_process_product_file_download_paths', $this->get_id(), 0, $value );
|
||||
}
|
||||
$updated = update_post_meta( $this->get_id(), $meta_key, $value );
|
||||
break;
|
||||
case 'image_id' :
|
||||
if ( ! empty( $value ) ) {
|
||||
set_post_thumbnail( $this->get_id(), $value );
|
||||
|
@ -1629,15 +1731,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
do_action( 'woocommerce_product_set_visibility', $this->get_id(), $this->get_catalog_visibility() );
|
||||
}
|
||||
|
||||
if ( in_array( 'downloads', $updated_props ) ) {
|
||||
// grant permission to any newly added files on any existing orders for this product prior to saving.
|
||||
if ( $this->is_type( 'variation' ) ) {
|
||||
do_action( 'woocommerce_process_product_file_download_paths', $this->get_parent_id(), $this->get_id(), $this->get_downloads() );
|
||||
} else {
|
||||
do_action( 'woocommerce_process_product_file_download_paths', $this->get_id(), 0, $this->get_downloads() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( 'stock_quantity', $updated_props ) ) {
|
||||
do_action( $this->is_type( 'variation' ) ? 'woocommerce_variation_set_stock' : 'woocommerce_product_set_stock' , $this );
|
||||
}
|
||||
|
@ -1699,6 +1792,24 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
update_post_meta( $this->get_id(), '_product_attributes', $meta_values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update downloads.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
protected function update_downloads() {
|
||||
$downloads = $this->get_downloads();
|
||||
$meta_values = array();
|
||||
|
||||
if ( $downloads ) {
|
||||
foreach ( $downloads as $key => $download ) {
|
||||
// Store in format WC uses in meta.
|
||||
$meta_values[ $key ] = $download->get_data();
|
||||
}
|
||||
}
|
||||
update_post_meta( $this->get_id(), '_downloadable_files', $meta_values );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Conditionals
|
||||
|
@ -1831,7 +1942,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function has_dimensions() {
|
||||
return $this->get_length() || $this->get_height() || $this->get_width();
|
||||
return ( $this->get_length() || $this->get_height() || $this->get_width() ) && ! $this->get_virtual();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1840,7 +1951,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function has_weight() {
|
||||
return $this->get_weight() ? true : false;
|
||||
return $this->get_weight() && ! $this->get_virtual();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1929,15 +2040,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return ! $this->managing_stock() || $this->backorders_allowed() || $this->get_stock_quantity() >= $quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not we are showing dimensions on the product page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enable_dimensions_display() {
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', ! $this->get_virtual() ) && ( $this->has_dimensions() || $this->has_weight() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the product has any visible attributes.
|
||||
*
|
||||
|
@ -1961,6 +2063,38 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return 0 < count( $this->get_children() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have dimensions?
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return bool
|
||||
*/
|
||||
public function child_has_dimensions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have a weight?
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_weight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if downloadable product has a file attached.
|
||||
*
|
||||
* @since 1.6.2
|
||||
*
|
||||
* @param string $download_id file identifier
|
||||
* @return bool Whether downloadable product has a file attached.
|
||||
*/
|
||||
public function has_file( $download_id = '' ) {
|
||||
return $this->is_downloadable() && $this->get_file( $download_id );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Non-CRUD Getters
|
||||
|
@ -2108,56 +2242,21 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return $attribute_object->is_taxonomy() ? implode( ', ', wc_get_product_terms( $this->get_id(), $attribute_object->get_name(), array( 'fields' => 'names' ) ) ) : wc_implode_text_attributes( $attribute_object->get_options() );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| @todo download functions
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if downloadable product has a file attached.
|
||||
*
|
||||
* @since 1.6.2
|
||||
*
|
||||
* @param string $download_id file identifier
|
||||
* @return bool Whether downloadable product has a file attached.
|
||||
* Get the total amount (COUNT) of ratings, or just the count for one rating e.g. number of 5 star ratings.
|
||||
* @param int $value Optional. Rating value to get the count for. By default returns the count of all rating values.
|
||||
* @return int
|
||||
*/
|
||||
public function has_file( $download_id = '' ) {
|
||||
return ( $this->is_downloadable() && $this->get_file( $download_id ) ) ? true : false;
|
||||
}
|
||||
public function get_rating_count( $value = null ) {
|
||||
$counts = $this->get_rating_counts();
|
||||
|
||||
/**
|
||||
* Gets an array of downloadable files for this product.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_files() {
|
||||
$downloads = $this->get_downloads();
|
||||
$downloadable_files = array_filter( ! empty( $downloads ) ? (array) maybe_unserialize( $downloads ) : array() );
|
||||
if ( ! empty( $downloadable_files ) ) {
|
||||
|
||||
foreach ( $downloadable_files as $key => $file ) {
|
||||
|
||||
if ( ! is_array( $file ) ) {
|
||||
$downloadable_files[ $key ] = array(
|
||||
'file' => $file,
|
||||
'name' => '',
|
||||
);
|
||||
}
|
||||
|
||||
// Set default name
|
||||
if ( empty( $file['name'] ) ) {
|
||||
$downloadable_files[ $key ]['name'] = wc_get_filename_from_url( $file['file'] );
|
||||
}
|
||||
|
||||
// Filter URL
|
||||
$downloadable_files[ $key ]['file'] = apply_filters( 'woocommerce_file_download_path', $downloadable_files[ $key ]['file'], $this, $key );
|
||||
}
|
||||
if ( is_null( $value ) ) {
|
||||
return array_sum( $counts );
|
||||
} elseif ( isset( $counts[ $value ] ) ) {
|
||||
return absint( $counts[ $value ] );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_product_files', $downloadable_files, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2167,8 +2266,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* @return array|false if not found
|
||||
*/
|
||||
public function get_file( $download_id = '' ) {
|
||||
|
||||
$files = $this->get_files();
|
||||
$files = $this->get_downloads();
|
||||
|
||||
if ( '' === $download_id ) {
|
||||
$file = sizeof( $files ) ? current( $files ) : false;
|
||||
|
@ -2178,7 +2276,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
$file = false;
|
||||
}
|
||||
|
||||
// allow overriding based on the particular file being requested
|
||||
return apply_filters( 'woocommerce_product_file', $file, $this, $download_id );
|
||||
}
|
||||
|
||||
|
@ -2189,197 +2286,10 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
* @return string
|
||||
*/
|
||||
public function get_file_download_path( $download_id ) {
|
||||
$files = $this->get_files();
|
||||
|
||||
if ( isset( $files[ $download_id ] ) ) {
|
||||
$file_path = $files[ $download_id ]['file'];
|
||||
} else {
|
||||
$file_path = '';
|
||||
}
|
||||
$files = $this->get_downloads();
|
||||
$file_path = isset( $files[ $download_id ] ) ? $files[ $download_id ]->get_file() : '';
|
||||
|
||||
// allow overriding based on the particular file being requested
|
||||
return apply_filters( 'woocommerce_product_file_download_path', $file_path, $this, $download_id );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| @todo misc
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Does a child have dimensions set?
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return bool
|
||||
*/
|
||||
public function child_has_dimensions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have a weight set?
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_weight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted dimensions.
|
||||
* @return string
|
||||
*/
|
||||
public function get_dimensions() {
|
||||
$dimensions = implode( ' x ', array_filter( array(
|
||||
wc_format_localized_decimal( $this->get_length() ),
|
||||
wc_format_localized_decimal( $this->get_width() ),
|
||||
wc_format_localized_decimal( $this->get_height() ),
|
||||
) ) );
|
||||
|
||||
if ( ! empty( $dimensions ) ) {
|
||||
$dimensions .= ' ' . get_option( 'woocommerce_dimension_unit' );
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the average rating of product. This is calculated once and stored in postmeta.
|
||||
* @return string
|
||||
*/
|
||||
public function get_average_rating() {
|
||||
// No meta data? Do the calculation
|
||||
if ( ! metadata_exists( 'post', $this->get_id(), '_wc_average_rating' ) ) {
|
||||
$this->sync_average_rating( $this->get_id() );
|
||||
}
|
||||
|
||||
return (string) floatval( get_post_meta( $this->get_id(), '_wc_average_rating', true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total amount (COUNT) of ratings.
|
||||
* @param int $value Optional. Rating value to get the count for. By default returns the count of all rating values.
|
||||
* @return int
|
||||
*/
|
||||
public function get_rating_count( $value = null ) {
|
||||
// No meta data? Do the calculation
|
||||
if ( ! metadata_exists( 'post', $this->get_id(), '_wc_rating_count' ) ) {
|
||||
$this->sync_rating_count( $this->get_id() );
|
||||
}
|
||||
|
||||
$counts = get_post_meta( $this->get_id(), '_wc_rating_count', true );
|
||||
|
||||
if ( is_null( $value ) ) {
|
||||
return array_sum( $counts );
|
||||
} else {
|
||||
return isset( $counts[ $value ] ) ? $counts[ $value ] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync product rating. Can be called statically.
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function sync_average_rating( $post_id ) {
|
||||
if ( ! metadata_exists( 'post', $post_id, '_wc_rating_count' ) ) {
|
||||
self::sync_rating_count( $post_id );
|
||||
}
|
||||
|
||||
$count = array_sum( (array) get_post_meta( $post_id, '_wc_rating_count', true ) );
|
||||
|
||||
if ( $count ) {
|
||||
global $wpdb;
|
||||
|
||||
$ratings = $wpdb->get_var( $wpdb->prepare("
|
||||
SELECT SUM(meta_value) FROM $wpdb->commentmeta
|
||||
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
|
||||
WHERE meta_key = 'rating'
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
AND meta_value > 0
|
||||
", $post_id ) );
|
||||
$average = number_format( $ratings / $count, 2, '.', '' );
|
||||
} else {
|
||||
$average = 0;
|
||||
}
|
||||
update_post_meta( $post_id, '_wc_average_rating', $average );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync product rating count. Can be called statically.
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function sync_rating_count( $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$counts = array();
|
||||
$raw_counts = $wpdb->get_results( $wpdb->prepare( "
|
||||
SELECT meta_value, COUNT( * ) as meta_value_count FROM $wpdb->commentmeta
|
||||
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
|
||||
WHERE meta_key = 'rating'
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
AND meta_value > 0
|
||||
GROUP BY meta_value
|
||||
", $post_id ) );
|
||||
|
||||
foreach ( $raw_counts as $count ) {
|
||||
$counts[ $count->meta_value ] = $count->meta_value_count;
|
||||
}
|
||||
|
||||
update_post_meta( $post_id, '_wc_rating_count', $counts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product rating in html format.
|
||||
*
|
||||
* @param string $rating (default: '')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_rating_html( $rating = null ) {
|
||||
$rating_html = '';
|
||||
|
||||
if ( ! is_numeric( $rating ) ) {
|
||||
$rating = $this->get_average_rating();
|
||||
}
|
||||
|
||||
if ( $rating > 0 ) {
|
||||
|
||||
$rating_html = '<div class="star-rating" title="' . sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $rating ) . '">';
|
||||
|
||||
$rating_html .= '<span style="width:' . ( ( $rating / 5 ) * 100 ) . '%"><strong class="rating">' . $rating . '</strong> ' . __( 'out of 5', 'woocommerce' ) . '</span>';
|
||||
|
||||
$rating_html .= '</div>';
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_product_get_rating_html', $rating_html, $rating );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total amount (COUNT) of reviews.
|
||||
*
|
||||
* @since 2.3.2
|
||||
* @return int The total numver of product reviews
|
||||
*/
|
||||
public function get_review_count() {
|
||||
global $wpdb;
|
||||
|
||||
// No meta date? Do the calculation
|
||||
if ( ! metadata_exists( 'post', $this->get_id(), '_wc_review_count' ) ) {
|
||||
$count = $wpdb->get_var( $wpdb->prepare("
|
||||
SELECT COUNT(*) FROM $wpdb->comments
|
||||
WHERE comment_parent = 0
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
", $this->get_id() ) );
|
||||
|
||||
update_post_meta( $this->get_id(), '_wc_review_count', $count );
|
||||
} else {
|
||||
$count = get_post_meta( $this->get_id(), '_wc_review_count', true );
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_product_review_count', $count, $this );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2247,7 +2247,7 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
|
||||
$product = wc_get_product( $product_id );
|
||||
$existing_download_ids = array_keys( (array) $product->get_files() );
|
||||
$existing_download_ids = array_keys( (array) $product->get_downloads() );
|
||||
$updated_download_ids = array_keys( (array) $downloadable_files );
|
||||
|
||||
$new_download_ids = array_filter( array_diff( $updated_download_ids, $existing_download_ids ) );
|
||||
|
|
|
@ -238,7 +238,7 @@ class WC_REST_Products_Controller extends WC_REST_Posts_Controller {
|
|||
$downloads = array();
|
||||
|
||||
if ( $product->is_downloadable() ) {
|
||||
foreach ( $product->get_files() as $file_id => $file ) {
|
||||
foreach ( $product->get_downloads() as $file_id => $file ) {
|
||||
$downloads[] = array(
|
||||
'id' => $file_id, // MD5 hash.
|
||||
'name' => $file['name'],
|
||||
|
|
|
@ -533,7 +533,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
if ( $product->is_downloadable() ) {
|
||||
|
||||
foreach ( $product->get_files() as $file_id => $file ) {
|
||||
foreach ( $product->get_downloads() as $file_id => $file ) {
|
||||
|
||||
$downloads[] = array(
|
||||
'id' => $file_id, // do not cast as int as this is a hash
|
||||
|
|
|
@ -1944,7 +1944,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
if ( $product->is_downloadable() ) {
|
||||
|
||||
foreach ( $product->get_files() as $file_id => $file ) {
|
||||
foreach ( $product->get_downloads() as $file_id => $file ) {
|
||||
|
||||
$downloads[] = array(
|
||||
'id' => $file_id, // do not cast as int as this is a hash
|
||||
|
|
|
@ -2529,7 +2529,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
if ( $product->is_downloadable() ) {
|
||||
|
||||
foreach ( $product->get_files() as $file_id => $file ) {
|
||||
foreach ( $product->get_downloads() as $file_id => $file ) {
|
||||
|
||||
$downloads[] = array(
|
||||
'id' => $file_id, // do not cast as int as this is a hash
|
||||
|
|
|
@ -781,7 +781,7 @@ class WC_AJAX {
|
|||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
$files = $product->get_files();
|
||||
$files = $product->get_downloads();
|
||||
|
||||
if ( ! $order->get_billing_email() ) {
|
||||
die();
|
||||
|
@ -797,8 +797,8 @@ class WC_AJAX {
|
|||
$loop ++;
|
||||
$file_counter ++;
|
||||
|
||||
if ( isset( $file['name'] ) ) {
|
||||
$file_count = $file['name'];
|
||||
if ( $file->get_name() ) {
|
||||
$file_count = $file->get_name();
|
||||
} else {
|
||||
$file_count = sprintf( __( 'File %d', 'woocommerce' ), $file_counter );
|
||||
}
|
||||
|
|
|
@ -238,10 +238,10 @@ class WC_Comments {
|
|||
public static function clear_transients( $post_id ) {
|
||||
|
||||
if ( 'product' === get_post_type( $post_id ) ) {
|
||||
delete_post_meta( $post_id, '_wc_average_rating' );
|
||||
delete_post_meta( $post_id, '_wc_rating_count' );
|
||||
delete_post_meta( $post_id, '_wc_review_count' );
|
||||
WC_Product::sync_average_rating( $post_id );
|
||||
$product = wc_get_product( $post_id );
|
||||
update_post_meta( $post_id, '_wc_rating_count', self::get_rating_counts_for_product( $product ) );
|
||||
update_post_meta( $post_id, '_wc_average_rating', self::get_average_rating_for_product( $product ) );
|
||||
update_post_meta( $post_id, '_wc_review_count', self::get_review_count_for_product( $product ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,6 +328,89 @@ class WC_Comments {
|
|||
}
|
||||
return $verified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product rating for a product. Please note this is not cached.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WC_Product $product
|
||||
* @return float
|
||||
*/
|
||||
public static function get_average_rating_for_product( $product ) {
|
||||
global $wpdb;
|
||||
|
||||
$count = $product->get_rating_count();
|
||||
|
||||
if ( $count ) {
|
||||
$ratings = $wpdb->get_var( $wpdb->prepare("
|
||||
SELECT SUM(meta_value) FROM $wpdb->commentmeta
|
||||
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
|
||||
WHERE meta_key = 'rating'
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
AND meta_value > 0
|
||||
", $product->get_id() ) );
|
||||
$average = number_format( $ratings / $count, 2, '.', '' );
|
||||
} else {
|
||||
$average = 0;
|
||||
}
|
||||
|
||||
update_post_meta( $product->get_id(), '_wc_average_rating', true );
|
||||
|
||||
return $average;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product review count for a product (not replies). Please note this is not cached.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WC_Product $product
|
||||
* @return int
|
||||
*/
|
||||
public static function get_review_count_for_product( $product ) {
|
||||
global $wpdb;
|
||||
|
||||
$count = $wpdb->get_var( $wpdb->prepare("
|
||||
SELECT COUNT(*) FROM $wpdb->comments
|
||||
WHERE comment_parent = 0
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
", $product->get_id() ) );
|
||||
|
||||
update_post_meta( $product->get_id(), '_wc_review_count', true );
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product rating count for a product. Please note this is not cached.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WC_Product $product
|
||||
* @return array of integers
|
||||
*/
|
||||
public static function get_rating_counts_for_product( $product ) {
|
||||
global $wpdb;
|
||||
|
||||
$counts = array();
|
||||
$raw_counts = $wpdb->get_results( $wpdb->prepare( "
|
||||
SELECT meta_value, COUNT( * ) as meta_value_count FROM $wpdb->commentmeta
|
||||
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
|
||||
WHERE meta_key = 'rating'
|
||||
AND comment_post_ID = %d
|
||||
AND comment_approved = '1'
|
||||
AND meta_value > 0
|
||||
GROUP BY meta_value
|
||||
", $product->get_id() ) );
|
||||
|
||||
foreach ( $raw_counts as $count ) {
|
||||
$counts[ $count->meta_value ] = absint( $count->meta_value_count );
|
||||
}
|
||||
|
||||
update_post_meta( $product->get_id(), '_wc_rating_count', true );
|
||||
|
||||
return $counts;
|
||||
}
|
||||
}
|
||||
|
||||
WC_Comments::init();
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a file which can be downloaded.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
* @package WooCommerce/Classes
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_Product_Download implements ArrayAccess {
|
||||
|
||||
/**
|
||||
* Data array.
|
||||
* @since 2.7.0
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array(
|
||||
'id' => '',
|
||||
'name' => '',
|
||||
'file' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns all data for this object.
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed mime types.
|
||||
* @return array
|
||||
*/
|
||||
public function get_allowed_mime_types() {
|
||||
return apply_filters( 'woocommerce_downloadable_file_allowed_mime_types', get_allowed_mime_types() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type of file path set.
|
||||
* @param string $file_path optional.
|
||||
* @return string absolute, relative, or shortcode.
|
||||
*/
|
||||
public function get_type_of_file_path( $file_path = '' ) {
|
||||
$file_path = $file_path ? $file_path : $this->get_file();
|
||||
if ( 0 === strpos( $file_path, 'http' ) ) {
|
||||
return 'absolute';
|
||||
} elseif ( '[' === substr( $file_path, 0, 1 ) && ']' === substr( $file_path, -1 ) ) {
|
||||
return 'shortcode';
|
||||
} else {
|
||||
return 'relative';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file type.
|
||||
* @return string
|
||||
*/
|
||||
public function get_file_type() {
|
||||
$type = wp_check_filetype( strtok( $this->get_file(), '?' ), $this->get_allowed_mime_types() );
|
||||
return $type['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file extension.
|
||||
* @return string
|
||||
*/
|
||||
public function get_file_extension() {
|
||||
$parsed_url = parse_url( $this->get_file(), PHP_URL_PATH );
|
||||
return pathinfo( $parsed_url, PATHINFO_EXTENSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file is allowed.
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_allowed_filetype() {
|
||||
if ( 'shortcode' === $this->get_type_of_file_path() ) {
|
||||
return true;
|
||||
}
|
||||
return empty( $this->get_file_extension() ) || in_array( $this->get_file_type(), $this->get_allowed_mime_types() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate file exists.
|
||||
* @return boolean
|
||||
*/
|
||||
public function file_exists() {
|
||||
if ( 'relative' !== $this->get_type_of_file_path() ) {
|
||||
return true;
|
||||
}
|
||||
$file_url = $this->get_file();
|
||||
if ( '..' === substr( $file_url, 0, 2 ) || '/' !== substr( $file_url, 0, 1 ) ) {
|
||||
$file_url = realpath( ABSPATH . $file_url );
|
||||
}
|
||||
return apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $file_url ), $this->get_file() );
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Setters
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set ID.
|
||||
* @param string $value
|
||||
*/
|
||||
public function set_id( $value ) {
|
||||
$this->data['id'] = wc_clean( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name.
|
||||
* @param string $value
|
||||
*/
|
||||
public function set_name( $value ) {
|
||||
$this->data['name'] = wc_clean( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file.
|
||||
* @param string $value
|
||||
*/
|
||||
public function set_file( $value ) {
|
||||
switch ( $this->get_type_of_file_path( $value ) ) {
|
||||
case 'absolute' :
|
||||
$this->data['file'] = esc_url_raw( $value );
|
||||
break;
|
||||
default:
|
||||
$this->data['file'] = wc_clean( $value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Getters
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->data['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return $this->data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file.
|
||||
* @return string
|
||||
*/
|
||||
public function get_file() {
|
||||
return $this->data['file'];
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ArrayAccess/Backwards compatibility.
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* offsetGet
|
||||
* @param string $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
switch ( $offset ) {
|
||||
default :
|
||||
if ( is_callable( array( $this, "get_$offset" ) ) ) {
|
||||
return $this->{"get_$offset"}();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* offsetSet
|
||||
* @param string $offset
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
switch ( $offset ) {
|
||||
default :
|
||||
if ( is_callable( array( $this, "set_$offset" ) ) ) {
|
||||
return $this->{"set_$offset"}( $value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* offsetUnset
|
||||
* @param string $offset
|
||||
*/
|
||||
public function offsetUnset( $offset ) {}
|
||||
|
||||
/**
|
||||
* offsetExists
|
||||
* @param string $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
return in_array( $offset, array_keys( $this->data ) );
|
||||
}
|
||||
}
|
|
@ -255,8 +255,8 @@ class WC_Product_Variable extends WC_Product {
|
|||
|
||||
return apply_filters( 'woocommerce_available_variation', array_merge( $variation->get_data(), array(
|
||||
'image' => wc_get_product_attachment_props( $variation->get_image_id() ),
|
||||
'weight_html' => $variation->get_weight() ? $variation->get_weight() . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ) : '',
|
||||
'dimensions_html' => $variation->get_dimensions(),
|
||||
'weight_html' => wc_format_weight( $variation->get_weight() ),
|
||||
'dimensions_html' => wc_format_dimensions( $variation->get_dimensions( false ) ),
|
||||
'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' => wc_get_stock_html( $variation ),
|
||||
'variation_id' => $variation->get_id(),
|
||||
|
@ -265,7 +265,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
'is_purchasable' => $variation->is_purchasable(),
|
||||
'display_price' => wc_get_price_to_display( $variation ),
|
||||
'display_regular_price' => wc_get_price_to_display( $variation, array( 'price' => $variation->get_regular_price() ) ),
|
||||
'dimensions' => $variation->get_dimensions(),
|
||||
'dimensions' => wc_format_dimensions( $variation->get_dimensions( false ) ),
|
||||
'min_qty' => 1,
|
||||
'max_qty' => $variation->backorders_allowed() ? '' : $variation->get_stock_quantity(),
|
||||
'backorders_allowed' => $variation->backorders_allowed(),
|
||||
|
@ -634,7 +634,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function has_dimensions() {
|
||||
return $this->get_length() || $this->get_height() || $this->get_width();
|
||||
return parent::has_dimensions() || $this->child_has_dimensions();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -643,16 +643,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function has_weight() {
|
||||
return $this->get_weight() ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not we are showing dimensions on the product page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enable_dimensions_display() {
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() || $this->child_has_weight() || $this->child_has_dimensions() );
|
||||
return parent::has_weight() || $this->child_has_weight();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -987,7 +987,7 @@ class WC_CLI_Product extends WC_CLI_Command {
|
|||
|
||||
if ( $product->is_downloadable() ) {
|
||||
|
||||
foreach ( $product->get_files() as $file_id => $file ) {
|
||||
foreach ( $product->get_downloads() as $file_id => $file ) {
|
||||
|
||||
$downloads[] = array(
|
||||
'id' => $file_id, // do not cast as int as this is a hash
|
||||
|
|
|
@ -279,3 +279,14 @@ function wc_check_if_attribute_name_is_reserved( $attribute_name ) {
|
|||
|
||||
return in_array( $attribute_name, $reserved_terms );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for array filter to get visible only.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WC_Product $product
|
||||
* @return bool
|
||||
*/
|
||||
function wc_attributes_array_filter_visible( $attribute ) {
|
||||
return $attribute && is_a( $attribute, 'WC_Product_Attribute' ) && $attribute->get_visible() && ( ! $attribute->is_taxonomy() || taxonomy_exists( $attribute->get_name() ) );
|
||||
}
|
||||
|
|
|
@ -1407,21 +1407,6 @@ function wc_get_logger() {
|
|||
return new $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a deprecated action with notice only if used.
|
||||
* @since 2.7.0
|
||||
* @param string $action
|
||||
* @param array $args
|
||||
* @param string $deprecated_in
|
||||
* @param string $replacement
|
||||
*/
|
||||
function wc_do_deprecated_action( $action, $args, $deprecated_in, $replacement ) {
|
||||
if ( has_action( $action ) ) {
|
||||
_deprecated_function( 'Action: ' . $action, $deprecated_in, $replacement );
|
||||
do_action_ref_array( $action, $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store user agents. Used for tracker.
|
||||
* @since 2.7.0
|
||||
|
|
|
@ -11,7 +11,55 @@
|
|||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a deprecated action with notice only if used.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $action
|
||||
* @param array $args
|
||||
* @param string $deprecated_in
|
||||
* @param string $replacement
|
||||
*/
|
||||
function wc_do_deprecated_action( $action, $args, $deprecated_in, $replacement ) {
|
||||
if ( has_action( $action ) ) {
|
||||
_deprecated_function( 'Action: ' . $action, $deprecated_in, $replacement );
|
||||
do_action_ref_array( $action, $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft deprecate a function so that it's technically deprecated, but not shown
|
||||
* until a future version to ease transition for developers.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $function
|
||||
* @param string $version
|
||||
* @param string $deprecate_in_version
|
||||
* @param string $replacement
|
||||
*/
|
||||
function wc_soft_deprecated_function( $function, $version, $deprecate_in_version, $replacement = null ) {
|
||||
if ( version_compare( WC_VERSION, $deprecate_in_version, '>=' ) ) {
|
||||
_deprecated_function( $function, $version, $replacement );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft deprecate an argument so that it's technically deprecated, but not shown
|
||||
* until a future version to ease transition for developers.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $argument
|
||||
* @param string $version
|
||||
* @param string $deprecate_in_version
|
||||
* @param string $replacement
|
||||
*/
|
||||
function wc_soft_deprecated_argument( $argument, $version, $deprecate_in_version, $message = null ) {
|
||||
if ( version_compare( WC_VERSION, $deprecate_in_version, '>=' ) ) {
|
||||
_deprecated_argument( $argument, $version, $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -523,6 +571,8 @@ $wc_map_deprecated_filters = array(
|
|||
'woocommerce_product_get_stock_quantity' => 'woocommerce_get_stock_quantity',
|
||||
'woocommerce_product_get_attributes' => 'woocommerce_get_product_attributes',
|
||||
'woocommerce_product_get_gallery_image_ids' => 'woocommerce_product_gallery_attachment_ids',
|
||||
'woocommerce_product_get_review_count' => 'woocommerce_product_review_count',
|
||||
'woocommerce_product_get_downloads' => 'woocommerce_product_files',
|
||||
);
|
||||
|
||||
foreach ( $wc_map_deprecated_filters as $new => $old ) {
|
||||
|
|
|
@ -959,3 +959,41 @@ function wc_format_price_range( $from, $to ) {
|
|||
$price = sprintf( _x( '%1$s – %2$s', 'Price range: from-to', 'woocommerce' ), is_numeric( $from ) ? wc_price( $from ) : $from, is_numeric( $to ) ? wc_price( $to ) : $to );
|
||||
return apply_filters( 'woocommerce_format_price_range', $price, $from, $to );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a weight for display.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param float $weight Weight.
|
||||
* @return string
|
||||
*/
|
||||
function wc_format_weight( $weight ) {
|
||||
$weight_string = wc_format_localized_decimal( $weight );
|
||||
|
||||
if ( ! empty( $weight_string ) ) {
|
||||
$weight_string .= ' ' . get_option( 'woocommerce_weight_unit' );
|
||||
} else {
|
||||
$weight_string = __( 'N/A', 'woocommerce' );
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_format_weight', $weight_string, $weight );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format dimensions for display.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $dimensions Array of dimensions.
|
||||
* @return string
|
||||
*/
|
||||
function wc_format_dimensions( $dimensions ) {
|
||||
$dimension_string = implode( ' x ', array_filter( array_map( 'wc_format_localized_decimal', $dimensions ) ) );
|
||||
|
||||
if ( ! empty( $dimension_string ) ) {
|
||||
$dimension_string .= ' ' . get_option( 'woocommerce_dimension_unit' );
|
||||
} else {
|
||||
$dimension_string = __( 'N/A', 'woocommerce' );
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_format_dimensions', $dimension_string, $dimensions );
|
||||
}
|
||||
|
|
|
@ -497,7 +497,7 @@ function wc_downloadable_product_permissions( $order_id ) {
|
|||
$_product = $item->get_product();
|
||||
|
||||
if ( $_product && $_product->exists() && $_product->is_downloadable() ) {
|
||||
$downloads = $_product->get_files();
|
||||
$downloads = $_product->get_downloads();
|
||||
|
||||
foreach ( array_keys( $downloads ) as $download_id ) {
|
||||
wc_downloadable_file_permission( $download_id, $item['variation_id'] > 0 ? $item['variation_id'] : $item['product_id'], $order, $item['qty'] );
|
||||
|
|
|
@ -1133,7 +1133,7 @@ if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) {
|
|||
}
|
||||
|
||||
// Additional information tab - shows attributes
|
||||
if ( $product && ( $product->has_attributes() || $product->enable_dimensions_display() ) ) {
|
||||
if ( $product && ( $product->has_attributes() || apply_filters( 'wc_product_enable_dimensions_display', $product->has_weight() || $product->has_dimensions() ) ) ) {
|
||||
$tabs['additional_information'] = array(
|
||||
'title' => __( 'Additional information', 'woocommerce' ),
|
||||
'priority' => 20,
|
||||
|
@ -2466,13 +2466,15 @@ if ( ! function_exists( 'woocommerce_photoswipe' ) ) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Outputs a list of product attributes.
|
||||
* Outputs a list of product attributes for a product.
|
||||
* @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,
|
||||
'product' => $product,
|
||||
'attributes' => array_filter( $product->get_attributes(), 'wc_attributes_array_filter_visible' ),
|
||||
'display_dimensions' => apply_filters( 'wc_product_enable_dimensions_display', $product->has_weight() || $product->has_dimensions() ),
|
||||
) );
|
||||
}
|
||||
|
||||
|
@ -2528,3 +2530,21 @@ function wc_get_price_suffix( $product, $price = '', $qty = 1 ) {
|
|||
}
|
||||
return apply_filters( 'woocommerce_get_price_suffix', $price_display_suffix, $product );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML for ratings.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param float $rating Rating being shown.
|
||||
* @return string
|
||||
*/
|
||||
function wc_get_rating_html( $rating ) {
|
||||
if ( $rating > 0 ) {
|
||||
$rating_html = '<div class="star-rating" title="' . sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $rating ) . '">';
|
||||
$rating_html .= '<span style="width:' . ( ( $rating / 5 ) * 100 ) . '%"><strong class="rating">' . $rating . '</strong> ' . __( 'out of 5', 'woocommerce' ) . '</span>';
|
||||
$rating_html .= '</div>';
|
||||
} else {
|
||||
$rating_html = '';
|
||||
}
|
||||
return apply_filters( 'woocommerce_product_get_rating_html', $rating_html, $rating );
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class WC_Widget_Recent_Reviews extends WC_Widget {
|
|||
|
||||
$rating = intval( get_comment_meta( $comment->comment_ID, 'rating', true ) );
|
||||
|
||||
$rating_html = $_product->get_rating_html( $rating );
|
||||
$rating_html = wc_get_rating_html( $rating );
|
||||
|
||||
echo '<li><a href="' . esc_url( get_comment_link( $comment->comment_ID ) ) . '">';
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ global $product; ?>
|
|||
<span class="product-title"><?php echo $product->get_title(); ?></span>
|
||||
</a>
|
||||
<?php if ( ! empty( $show_rating ) ) : ?>
|
||||
<?php echo $product->get_rating_html(); ?>
|
||||
<?php echo wc_get_rating_html( $product->get_average_rating() ); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $product->get_price_html(); ?>
|
||||
</li>
|
||||
|
|
|
@ -17,17 +17,12 @@
|
|||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
exit;
|
||||
}
|
||||
|
||||
global $product;
|
||||
|
||||
if ( get_option( 'woocommerce_enable_review_rating' ) === 'no' )
|
||||
return;
|
||||
?>
|
||||
|
||||
<?php if ( $rating_html = $product->get_rating_html() ) : ?>
|
||||
<?php echo $rating_html; ?>
|
||||
<?php endif;
|
||||
|
||||
/* Omit closing PHP tag at the end of PHP files to avoid "headers already sent" issues. */
|
||||
echo wc_get_rating_html( $product->get_average_rating() );
|
||||
|
|
|
@ -19,66 +19,31 @@
|
|||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
exit;
|
||||
}
|
||||
|
||||
$has_row = false;
|
||||
$alt = 1;
|
||||
$attributes = $product->get_variation_attributes();
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<table class="shop_attributes">
|
||||
|
||||
<?php if ( $product->enable_dimensions_display() ) : ?>
|
||||
|
||||
<?php if ( $product->has_weight() || $product->child_has_weight() ) : $has_row = true; ?>
|
||||
<tr class="<?php if ( ( $alt = $alt * -1 ) === 1 ) echo 'alt'; ?>">
|
||||
<th><?php _e( 'Weight', 'woocommerce' ) ?></th>
|
||||
<td class="product_weight"><?php echo $product->get_weight() ? wc_format_localized_decimal( $product->get_weight() ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ) : __( 'N/A', 'woocommerce' ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $product->has_dimensions() || $product->child_has_dimensions() ) : $has_row = true; ?>
|
||||
<tr class="<?php if ( ( $alt = $alt * -1 ) === 1 ) echo 'alt'; ?>">
|
||||
<th><?php _e( 'Dimensions', 'woocommerce' ) ?></th>
|
||||
<td class="product_dimensions"><?php echo $product->get_dimensions() ? $product->get_dimensions() : __( 'N/A', 'woocommerce' ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $display_dimensions && $product->has_weight() ) : ?>
|
||||
<tr>
|
||||
<th><?php _e( 'Weight', 'woocommerce' ) ?></th>
|
||||
<td class="product_weight"><?php echo esc_html( wc_format_weight( $product->get_weight() ) ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ( $attributes as $attribute ) :
|
||||
if ( empty( $attribute['is_visible'] ) || ( $attribute['is_taxonomy'] && ! taxonomy_exists( $attribute['name'] ) ) ) {
|
||||
continue;
|
||||
} else {
|
||||
$has_row = true;
|
||||
}
|
||||
?>
|
||||
<tr class="<?php if ( ( $alt = $alt * -1 ) == 1 ) echo 'alt'; ?>">
|
||||
<th><?php echo wc_attribute_label( $attribute['name'] ); ?></th>
|
||||
<?php if ( $display_dimensions && $product->has_dimensions() ) : ?>
|
||||
<tr>
|
||||
<th><?php _e( 'Dimensions', 'woocommerce' ) ?></th>
|
||||
<td class="product_dimensions"><?php echo esc_html( wc_format_dimensions( $product->get_dimensions( false ) ) ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ( $attributes as $attribute ) : ?>
|
||||
<tr>
|
||||
<th><?php echo wc_attribute_label( $attribute->get_name() ); ?></th>
|
||||
<td><?php
|
||||
if ( $attribute['is_taxonomy'] ) {
|
||||
|
||||
$values = wc_get_product_terms( $product->get_id(), $attribute['name'], array( 'fields' => 'names' ) );
|
||||
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
|
||||
|
||||
} else {
|
||||
|
||||
// Convert pipes to commas and display values
|
||||
$values = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) );
|
||||
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
|
||||
|
||||
}
|
||||
$values = $attribute->is_taxonomy() ? wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'names' ) ) : $attribute->get_options();
|
||||
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
|
||||
?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</table>
|
||||
<?php
|
||||
if ( $has_row ) {
|
||||
echo ob_get_clean();
|
||||
} else {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue