Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Diego Zanella 2015-03-27 18:09:58 +00:00
commit d420fcca29
11 changed files with 108 additions and 75 deletions

View File

@ -575,33 +575,29 @@ abstract class WC_Abstract_Order {
* @return bool success or fail
*/
public function calculate_taxes() {
$tax_total = 0;
$taxes = array();
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if ( 'base' === $tax_based_on ) {
if ( 'billing' === $tax_based_on ) {
$country = $this->billing_country;
$state = $this->billing_state;
$postcode = $this->billing_postcode;
$city = $this->billing_city;
} elseif ( 'shipping' === $tax_based_on ) {
$country = $this->shipping_country;
$state = $this->shipping_state;
$postcode = $this->shipping_postcode;
$city = $this->shipping_city;
}
// Default to base
if ( 'base' === $tax_based_on || empty( $country ) ) {
$default = wc_get_base_location();
$country = $default['country'];
$state = $default['state'];
$postcode = '';
$city = '';
} elseif ( 'billing' === $tax_based_on ) {
$country = $this->billing_country;
$state = $this->billing_state;
$postcode = $this->billing_postcode;
$city = $this->billing_city;
} else {
$country = $this->shipping_country;
$state = $this->shipping_state;
$postcode = $this->shipping_postcode;
$city = $this->shipping_city;
}
// Get items

View File

@ -953,10 +953,11 @@ class WC_Countries {
if ( $type == 'billing_' ) {
$address_fields['billing_email'] = array(
'label' => __( 'Email Address', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first' ),
'validate' => array( 'email' ),
'label' => __( 'Email Address', 'woocommerce' ),
'required' => true,
'type' => 'email',
'class' => array( 'form-row-first' ),
'validate' => array( 'email' ),
);
$address_fields['billing_phone'] = array(

View File

@ -121,10 +121,15 @@ class WC_Coupon {
$this->code = apply_filters( 'woocommerce_coupon_code', $code );
// Coupon data lets developers create coupons through code
if ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code ) ) {
if ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $this->code ) ) {
$this->populate( $coupon );
return true;
} elseif ( ( $this->id = $this->get_coupon_id_from_code( $code ) ) && $this->code === apply_filters( 'woocommerce_coupon_code', get_the_title( $this->id ) ) ) {
}
// Otherwise get ID from the code
$this->id = $this->get_coupon_id_from_code( $this->code );
if ( $this->code === apply_filters( 'woocommerce_coupon_code', get_the_title( $this->id ) ) ) {
$this->populate();
return true;
}
@ -336,7 +341,7 @@ class WC_Coupon {
* Ensure coupon amount is valid or throw exception
*/
private function validate_minimum_amount() {
if ( $this->minimum_amount > 0 && $this->minimum_amount > WC()->cart->subtotal ) {
if ( $this->minimum_amount > 0 && wc_format_decimal( $this->minimum_amount ) > wc_format_decimal( WC()->cart->subtotal ) ) {
throw new Exception( self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET );
}
}
@ -345,7 +350,7 @@ class WC_Coupon {
* Ensure coupon amount is valid or throw exception
*/
private function validate_maximum_amount() {
if ( $this->maximum_amount > 0 && $this->maximum_amount < WC()->cart->subtotal ) {
if ( $this->maximum_amount > 0 && wc_format_decimal( $this->minimum_amount ) < wc_format_decimal( WC()->cart->subtotal ) ) {
throw new Exception( self::E_WC_COUPON_MAX_SPEND_LIMIT_MET );
}
}

View File

@ -568,6 +568,9 @@ function wc_delete_shop_order_transients( $post_id = 0 ) {
delete_transient( $transient );
}
// Increments the transient version to invalidate cache
WC_Cache_Helper::get_transient_version( 'orders', true );
do_action( 'woocommerce_delete_shop_order_transients', $post_id );
}

View File

@ -198,23 +198,35 @@ function wc_get_featured_product_ids() {
*/
function wc_product_post_type_link( $permalink, $post ) {
// Abort if post is not a product
if ( $post->post_type !== 'product' )
if ( $post->post_type !== 'product' ) {
return $permalink;
}
// Abort early if the placeholder rewrite tag isn't in the generated URL
if ( false === strpos( $permalink, '%' ) )
if ( false === strpos( $permalink, '%' ) ) {
return $permalink;
}
// Get the custom taxonomy terms in use by this post
$terms = get_the_terms( $post->ID, 'product_cat' );
if ( empty( $terms ) ) {
if ( ! empty( $terms ) ) {
usort( $terms, '_usort_terms_by_ID' ); // order by ID
$category_object = apply_filters( 'wc_product_post_type_link_product_cat', $terms[0], $terms, $post );
$category_object = get_term( $category_object, 'product_cat' );
$product_cat = $category_object->slug;
if ( $parent = $category_object->parent ) {
$ancestors = get_ancestors( $category_object->term_id, 'product_cat' );
foreach ( $ancestors as $ancestor ) {
$ancestor_object = get_term( $ancestor, 'product_cat' );
$product_cat = $ancestor_object->slug . '/' . $product_cat;
}
}
} else {
// If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
$product_cat = _x( 'uncategorized', 'slug', 'woocommerce' );
} else {
// Replace the placeholder rewrite tag with the first term's slug
$first_term = array_shift( $terms );
$product_cat = $first_term->slug;
}
$find = array(
@ -241,8 +253,6 @@ function wc_product_post_type_link( $permalink, $post ) {
$product_cat
);
$replace = array_map( 'sanitize_title', $replace );
$permalink = str_replace( $find, $replace, $permalink );
return $permalink;

View File

@ -1770,6 +1770,23 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
$field .= '</p>' . $after;
break;
case 'email' :
$field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $args['id'] ) . '_field">';
if ( $args['label'] ) {
$field .= '<label for="' . esc_attr( $args['id'] ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) .'">' . $args['label'] . $required . '</label>';
}
$field .= '<input type="email" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
if ( $args['description'] ) {
$field .= '<span class="description">' . esc_attr( $args['description'] ) . '</span>';
}
$field .= '</p>' . $after;
break;
case 'select' :

View File

@ -210,7 +210,6 @@ add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' );
/**
* Checks if a user (by email) has bought an item
*
* @access public
* @param string $customer_email
* @param int $user_id
* @param int $product_id
@ -219,46 +218,47 @@ add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' );
function wc_customer_bought_product( $customer_email, $user_id, $product_id ) {
global $wpdb;
$emails = array();
$transient_name = 'wc_cbp_' . md5( $customer_email . $user_id . $product_id . WC_Cache_Helper::get_transient_version( 'orders' ) );
if ( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( false === ( $result = get_transient( $transient_name ) ) ) {
$customer_data = array( $user_id );
if ( isset( $user->user_email ) ) {
$emails[] = $user->user_email;
if ( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( isset( $user->user_email ) ) {
$customer_data[] = $user->user_email;
}
}
}
if ( is_email( $customer_email ) ) {
$emails[] = $customer_email;
}
if ( is_email( $customer_email ) ) {
$customer_data[] = $customer_email;
}
if ( sizeof( $emails ) == 0 ) {
return false;
}
$customer_data = array_filter( array_unique( $customer_data ) );
return $wpdb->get_var(
$wpdb->prepare( "
SELECT COUNT( DISTINCT order_items.order_item_id )
FROM {$wpdb->prefix}woocommerce_order_items as order_items
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta ON order_items.order_item_id = itemmeta.order_item_id
LEFT JOIN {$wpdb->postmeta} AS postmeta ON order_items.order_id = postmeta.post_id
LEFT JOIN {$wpdb->posts} AS posts ON order_items.order_id = posts.ID
WHERE
posts.post_status IN ( 'wc-completed', 'wc-processing' ) AND
itemmeta.meta_value = %s AND
itemmeta.meta_key IN ( '_variation_id', '_product_id' ) AND
postmeta.meta_key IN ( '_billing_email', '_customer_user' ) AND
(
postmeta.meta_value IN ( '" . implode( "','", array_unique( $emails ) ) . "' ) OR
(
postmeta.meta_value = %s AND
postmeta.meta_value > 0
)
)
", $product_id, $user_id
)
);
if ( sizeof( $customer_data ) == 0 ) {
return false;
}
$result = $wpdb->get_var(
$wpdb->prepare( "
SELECT 1 FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
WHERE p.post_status IN ( 'wc-completed', 'wc-processing' )
AND pm.meta_key IN ( '_billing_email', '_customer_user' )
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
AND im.meta_key IN ( '_product_id', '_variation_id' )
AND im.meta_value = %s
", $product_id
)
);
set_transient( $transient_name, $result ? 1 : 0, DAY_IN_SECONDS * 30 );
}
return (bool) $result;
}
/**
@ -406,7 +406,7 @@ function wc_get_customer_available_downloads( $customer_id ) {
", $customer_id, date( 'Y-m-d', current_time( 'timestamp' ) ) ) );
if ( $results ) {
$looped_downloads = array();
foreach ( $results as $result ) {
if ( ! $order || $order->id != $result->order_id ) {
@ -439,7 +439,7 @@ function wc_get_customer_available_downloads( $customer_id ) {
}
$download_file = $_product->get_file( $result->download_id );
// Check if the file has been already added to the downloads list
if ( in_array( $download_file, $looped_downloads ) ) {
continue;

View File

@ -138,6 +138,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
== Changelog ==
* Feature - Show full category hierarchy in permalinks.
* Fix - Ensure coupon taxes are reset when calculating totals.
* Tweak - Base discounts on the undiscounted price. #5874
@ -159,7 +160,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Fix - Settings API - allow multiselect fields to be emptied.
* Fix - Saving an order needs to save the discount amount ex. tax like the cart.
* Fix - Order again with custom attributes.
* Fix - Prevent potential XSS within tooltips (discovered by FortiGuard Labs).
* Fix - [CVE-2015-2329] Prevent potential XSS within tooltips (discovered by Fortinet FortiGuard Labs).
* Fix - Paypal debug option.
* Fix - Removed $q->query['wc_query'] = 'product_query' which broke redirects (#7703). Use $q->get('wc_query') instead.
* Fix - Sanitize tax_rate_id when saving taxes in the backend to prevent potential SQL injection (discovered by WordFence).

View File

@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<tr class="cart-discount coupon-<?php echo esc_attr( $code ); ?>">
<tr class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
<th><?php wc_cart_totals_coupon_label( $coupon ); ?></th>
<td><?php wc_cart_totals_coupon_html( $coupon ); ?></td>
</tr>

View File

@ -52,7 +52,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<tr class="cart-discount coupon-<?php echo esc_attr( $code ); ?>">
<tr class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
<th><?php wc_cart_totals_coupon_label( $coupon ); ?></th>
<td><?php wc_cart_totals_coupon_html( $coupon ); ?></td>
</tr>

View File

@ -17,7 +17,7 @@ foreach ( $items as $item_id => $item ) :
if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
?>
<tr>
<tr class="<?php echo esc_attr( apply_filters( 'woocoomerce_order_item_class', 'order_item', $item, $order ) ); ?>">
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee; word-wrap:break-word;"><?php
// Show title/image etc