Update from master

This commit is contained in:
Mike Jolley 2019-03-01 10:19:40 +00:00
commit 51dbbac32d
32 changed files with 256 additions and 167 deletions

View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#4267b2;}.cls-2{fill:#fff;}</style></defs><title>flogo_RGB_HEX-512</title><path class="cls-1" d="M483.74,0H28.26A28.26,28.26,0,0,0,0,28.26V483.74A28.26,28.26,0,0,0,28.26,512H273.5V314H207V236.5h66.5v-57c0-66.13,40.39-102.14,99.38-102.14,28.25,0,52.54,2.1,59.62,3v69.11l-40.68,0c-32.1,0-38.32,15.25-38.32,37.64V236.5h76.74l-10,77.5H353.5V512H483.74A28.26,28.26,0,0,0,512,483.74V28.26A28.26,28.26,0,0,0,483.74,0Z"/><path id="f" class="cls-2" d="M353.5,512V314h66.75l10-77.5H353.5V187.14c0-22.39,6.22-37.64,38.32-37.64l40.68,0V80.37c-7.08-.94-31.37-3-59.62-3-59,0-99.38,36-99.38,102.14v57H207V314h66.5V512Z"/></svg>

After

Width:  |  Height:  |  Size: 732 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -44,7 +44,19 @@ jQuery( function( $ ) {
} )
// Star ratings for comments
.on( 'init', '#rating', function() {
$( '#rating' ).hide().before( '<p class="stars"><span><a class="star-1" href="#">1</a><a class="star-2" href="#">2</a><a class="star-3" href="#">3</a><a class="star-4" href="#">4</a><a class="star-5" href="#">5</a></span></p>' );
$( '#rating' )
.hide()
.before(
'<p class="stars">\
<span>\
<a class="star-1" href="#">1</a>\
<a class="star-2" href="#">2</a>\
<a class="star-3" href="#">3</a>\
<a class="star-4" href="#">4</a>\
<a class="star-5" href="#">5</a>\
</span>\
</p>'
);
} )
.on( 'click', '#respond p.stars a', function() {
var $star = $( this ),
@ -210,6 +222,12 @@ jQuery( function( $ ) {
zoomTarget.trigger( 'zoom.destroy' );
zoomTarget.zoom( zoom_options );
setTimeout( function() {
if ( zoomTarget.find(':hover').length ) {
zoomTarget.trigger( 'mouseover' );
}
}, 100 );
}
};
@ -307,12 +325,12 @@ jQuery( function( $ ) {
* Initialize all galleries on page.
*/
$( '.woocommerce-product-gallery' ).each( function() {
$( this ).trigger( 'wc-product-gallery-before-init', [ this, wc_single_product_params ] );
$( this ).wc_product_gallery( wc_single_product_params );
$( this ).trigger( 'wc-product-gallery-after-init', [ this, wc_single_product_params ] );
} );
} );

View File

@ -7,7 +7,7 @@
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"composer/installers": "~1.6"
"composer/installers": "1.6.0"
},
"require-dev": {
"apigen/apigen": "4.1.2",

7
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "67b8066152baf2f08393562b576da266",
"content-hash": "e7a81f490b054c067759791d696be7bd",
"packages": [
{
"name": "composer/installers",
@ -247,7 +247,7 @@
"homepage": "https://github.com/kukulich"
},
{
"name": "Tomas Votruba",
"name": "Tomáš Votruba",
"email": "tomas.vot@gmail.com"
},
{
@ -2805,6 +2805,7 @@
"mock",
"xunit"
],
"abandoned": true,
"time": "2018-08-09T05:50:03+00:00"
},
{
@ -3731,7 +3732,7 @@
},
{
"name": "Gert de Pagter",
"email": "backendtea@gmail.com"
"email": "BackEndTea@gmail.com"
}
],
"description": "Symfony polyfill for ctype functions",

View File

@ -1444,7 +1444,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$cart_subtotal = 0;
$cart_total = 0;
$fee_total = 0;
$fees_total = 0;
$shipping_total = 0;
$cart_subtotal_tax = 0;
$cart_total_tax = 0;
@ -1464,18 +1464,17 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
// Sum fee costs.
foreach ( $this->get_fees() as $item ) {
$amount = $item->get_amount();
$fee_total = $item->get_total();
if ( 0 > $amount ) {
$item->set_total( $amount );
$max_discount = round( $cart_total + $fee_total + $shipping_total, wc_get_price_decimals() ) * -1;
if ( 0 > $fee_total ) {
$max_discount = round( $cart_total + $fees_total + $shipping_total, wc_get_price_decimals() ) * -1;
if ( $item->get_total() < $max_discount ) {
if ( $fee_total < $max_discount ) {
$item->set_total( $max_discount );
}
}
$fee_total += $item->get_total();
$fees_total += $item->get_total();
}
// Calculate taxes for items, shipping, discounts. Note; this also triggers save().
@ -1498,7 +1497,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$this->set_discount_total( $cart_subtotal - $cart_total );
$this->set_discount_tax( wc_round_tax_total( $cart_subtotal_tax - $cart_total_tax ) );
$this->set_total( round( $cart_total + $fee_total + $this->get_shipping_total() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals() ) );
$this->set_total( round( $cart_total + $fees_total + $this->get_shipping_total() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals() ) );
do_action( 'woocommerce_order_after_calculate_totals', $and_taxes, $this );

View File

@ -351,7 +351,7 @@ class WC_Admin_Notices {
* @todo Remove this notice and associated code once the feature plugin has been merged into core.
*/
public static function add_wootenberg_feature_plugin_notice() {
if ( ( is_plugin_active( 'gutenberg/gutenberg.php' ) || version_compare( get_bloginfo( 'version' ), '5.0', '>=' ) ) && ! is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) ) {
if ( ( self::is_plugin_active( 'gutenberg/gutenberg.php' ) || version_compare( get_bloginfo( 'version' ), '5.0', '>=' ) ) && ! self::is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) ) {
self::add_notice( 'wootenberg' );
}
}
@ -363,7 +363,7 @@ class WC_Admin_Notices {
* @todo Remove this notice and associated code once the feature plugin has been merged into core.
*/
public static function add_wootenberg_feature_plugin_notice_on_gutenberg_activate() {
if ( ! is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) && version_compare( get_bloginfo( 'version' ), '5.0', '<' ) ) {
if ( ! self::is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) && version_compare( get_bloginfo( 'version' ), '5.0', '<' ) ) {
self::add_notice( 'wootenberg' );
}
}
@ -372,7 +372,7 @@ class WC_Admin_Notices {
* Notice about trying the Products block.
*/
public static function wootenberg_feature_plugin_notice() {
if ( get_user_meta( get_current_user_id(), 'dismissed_wootenberg_notice', true ) || is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) ) {
if ( get_user_meta( get_current_user_id(), 'dismissed_wootenberg_notice', true ) || self::is_plugin_active( 'woo-gutenberg-products-block/woocommerce-gutenberg-products-block.php' ) ) {
self::remove_notice( 'wootenberg' );
return;
}
@ -392,6 +392,18 @@ class WC_Admin_Notices {
return ( is_ssl() && 'https' === substr( $shop_page, 0, 5 ) );
}
/**
* Wrapper for is_plugin_active.
*
* @param string $plugin Plugin to check.
* @return boolean
*/
protected static function is_plugin_active( $plugin ) {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php';
}
return is_plugin_active( $plugin );
}
}
WC_Admin_Notices::init();

View File

@ -392,8 +392,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
}
?>
>
<?php echo esc_html( $val ); ?></option>
><?php echo esc_html( $val ); ?></option>
<?php
}
?>

View File

@ -133,6 +133,21 @@ class WC_Admin_Setup_Wizard {
return current_user_can( 'install_plugins' );
}
/**
* Should we show the Facebook install option?
* True only if the user can install plugins,
* and up until the end date of the recommendation.
*
* @return boolean
*/
protected function should_show_facebook() {
$end_date_facebook_recommendation = new DateTime( '8 October 2019' );
$current_user_date = new DateTime( current_time( 'Y-m-d' ) );
return current_user_can( 'install_plugins' ) &&
$end_date_facebook_recommendation >= $current_user_date;
}
/**
* Should we display the 'Recommended' step?
* True if at least one of the recommendations will be displayed.
@ -142,7 +157,8 @@ class WC_Admin_Setup_Wizard {
protected function should_show_recommended_step() {
return $this->should_show_theme()
|| $this->should_show_automated_tax()
|| $this->should_show_mailchimp();
|| $this->should_show_mailchimp()
|| $this->should_show_facebook();
}
/**
@ -576,12 +592,13 @@ class WC_Admin_Setup_Wizard {
update_option( 'woocommerce_price_thousand_sep', $locale_info[ $country ]['thousand_sep'] );
}
}
if ( $tracking ) {
update_option( 'woocommerce_allow_tracking', 'yes' );
wp_schedule_single_event( time() + 10, 'woocommerce_tracker_send_event', array( true ) );
} else {
update_option( 'woocommerce_allow_tracking', 'no' );
if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) {
if ( $tracking ) {
update_option( 'woocommerce_allow_tracking', 'yes' );
wp_schedule_single_event( time() + 10, 'woocommerce_tracker_send_event', array( true ) );
} else {
update_option( 'woocommerce_allow_tracking', 'no' );
}
}
WC_Install::create_pages();
@ -1868,20 +1885,9 @@ class WC_Admin_Setup_Wizard {
public function wc_setup_recommended() {
?>
<h1><?php esc_html_e( 'Recommended for All WooCommerce Stores', 'woocommerce' ); ?></h1>
<p><?php
// If we're displaying all of the recommended features, show the full description. Otherwise, display a placeholder.
// We're not translating all of the different permutations to save on translations,
// and the default is the most common.
if (
$this->should_show_theme()
&& $this->should_show_automated_tax()
&& $this->should_show_mailchimp()
) :
esc_html_e( 'Select from the list below to enable automated taxes and MailChimps best-in-class email services — and design your store with our official, free WooCommerce theme.', 'woocommerce' );
else :
esc_html_e( 'Enhance your store with these recommended features.', 'woocommerce' );
endif;
?></p>
<p>
<?php esc_html_e( 'Enhance your store with these recommended features.', 'woocommerce' ); ?>
</p>
<form method="post">
<ul class="recommended-step">
<?php
@ -1921,6 +1927,17 @@ class WC_Admin_Setup_Wizard {
'plugins' => array( array( 'name' => __( 'Mailchimp for WooCommerce', 'woocommerce' ), 'slug' => 'mailchimp-for-woocommerce' ) ),
) );
endif;
if ( $this->should_show_facebook() ) :
$this->display_recommended_item( array(
'type' => 'facebook',
'title' => __( 'Facebook', 'woocommerce' ),
'description' => __( 'Enjoy all Facebook products combined in one extension: pixel tracking, catalog sync, messenger chat, shop functionality and Instagram shopping (coming soon)!', 'woocommerce' ),
'img_url' => WC()->plugin_url() . '/assets/images/obw-facebook-icon.svg',
'img_alt' => __( 'Facebook icon', 'woocommerce' ),
'plugins' => array( array( 'name' => __( 'Facebook for WooCommerce', 'woocommerce' ), 'slug' => 'facebook-for-woocommerce' ) ),
) );
endif;
?>
</ul>
<p class="wc-setup-actions step">
@ -1941,6 +1958,7 @@ class WC_Admin_Setup_Wizard {
$setup_storefront = isset( $_POST['setup_storefront_theme'] ) && 'yes' === $_POST['setup_storefront_theme'];
$setup_automated_tax = isset( $_POST['setup_automated_taxes'] ) && 'yes' === $_POST['setup_automated_taxes'];
$setup_mailchimp = isset( $_POST['setup_mailchimp'] ) && 'yes' === $_POST['setup_mailchimp'];
$setup_facebook = isset( $_POST['setup_facebook'] ) && 'yes' === $_POST['setup_facebook'];
update_option( 'woocommerce_calc_taxes', $setup_automated_tax ? 'yes' : 'no' );
update_option( 'woocommerce_setup_automated_taxes', $setup_automated_tax );
@ -1967,6 +1985,16 @@ class WC_Admin_Setup_Wizard {
);
}
if ( $setup_facebook ) {
$this->install_plugin(
'facebook-for-woocommerce',
array(
'name' => __( 'Facebook for WooCommerce', 'woocommerce' ),
'repo-slug' => 'facebook-for-woocommerce',
)
);
}
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}

View File

@ -333,6 +333,9 @@ class WC_AJAX {
}
WC()->customer->save();
// Calculate shipping before totals. This will ensure any shipping methods that affect things like taxes are chosen prior to final totals being calculated. Ref: #22708
WC()->cart->calculate_shipping();
WC()->cart->calculate_totals();
// Get order review fragment.
@ -632,21 +635,22 @@ class WC_AJAX {
ob_start();
$attributes = $product->get_attributes( 'edit' );
$i = -1;
if ( ! empty( $data['attribute_names'] ) ) {
foreach ( $data['attribute_names'] as $attribute_name ) {
$attribute = isset( $attributes[ sanitize_title( $attribute_name ) ] ) ? $attributes[ sanitize_title( $attribute_name ) ] : false;
if ( ! $attribute ) {
continue;
}
$i++;
$metabox_class = array();
foreach ( $data['attribute_names'] as $attribute_name ) {
$attribute = isset( $attributes[ sanitize_title( $attribute_name ) ] ) ? $attributes[ sanitize_title( $attribute_name ) ] : false;
if ( ! $attribute ) {
continue;
if ( $attribute->is_taxonomy() ) {
$metabox_class[] = 'taxonomy';
$metabox_class[] = $attribute->get_name();
}
include( 'admin/meta-boxes/views/html-product-attribute.php' );
}
$i++;
$metabox_class = array();
if ( $attribute->is_taxonomy() ) {
$metabox_class[] = 'taxonomy';
$metabox_class[] = $attribute->get_name();
}
include( 'admin/meta-boxes/views/html-product-attribute.php' );
}
$response['html'] = ob_get_clean();

View File

@ -23,6 +23,7 @@ class WC_Cache_Helper {
* Hook in methods.
*/
public static function init() {
add_filter( 'nocache_headers', array( __CLASS__, 'additional_nocache_headers' ), 10 );
add_action( 'shutdown', array( __CLASS__, 'delete_transients_on_shutdown' ), 10 );
add_action( 'template_redirect', array( __CLASS__, 'geolocation_ajax_redirect' ) );
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
@ -32,6 +33,18 @@ class WC_Cache_Helper {
add_action( 'edit_terms', array( __CLASS__, 'clean_term_cache' ), 10, 2 );
}
/**
* Set additonal nocache headers.
*
* @param array $headers Header names and field values.
* @since 3.6.0
*/
public static function additional_nocache_headers( $headers ) {
// Opt-out of Google weblight if page is dynamic e.g. cart/checkout. https://support.google.com/webmasters/answer/6211428?hl=en.
$headers['Cache-Control'] = 'no-transform, no-cache, must-revalidate, max-age=0';
return $headers;
}
/**
* Add a transient to delete on shutdown.
*

View File

@ -634,6 +634,9 @@ class WC_Cart extends WC_Legacy_Cart {
* @param bool $clear_persistent_cart Should the persistant cart be cleared too. Defaults to true.
*/
public function empty_cart( $clear_persistent_cart = true ) {
do_action( 'woocommerce_before_cart_emptied' );
$this->cart_contents = array();
$this->removed_cart_contents = array();
$this->shipping_methods = array();

View File

@ -965,7 +965,15 @@ class WC_Checkout {
if ( ! is_user_logged_in() && ( $this->is_registration_required() || ! empty( $data['createaccount'] ) ) ) {
$username = ! empty( $data['account_username'] ) ? $data['account_username'] : '';
$password = ! empty( $data['account_password'] ) ? $data['account_password'] : '';
$customer_id = wc_create_new_customer( $data['billing_email'], $username, $password );
$customer_id = wc_create_new_customer(
$data['billing_email'],
$username,
$password,
array(
'first_name' => ! empty( $data['billing_first_name'] ) ? $data['billing_first_name'] : '',
'last_name' => ! empty( $data['billing_last_name'] ) ? $data['billing_last_name'] : '',
)
);
if ( is_wp_error( $customer_id ) ) {
throw new Exception( $customer_id->get_error_message() );
@ -989,17 +997,17 @@ class WC_Checkout {
if ( $customer_id && apply_filters( 'woocommerce_checkout_update_customer_data', true, $this ) ) {
$customer = new WC_Customer( $customer_id );
if ( ! empty( $data['billing_first_name'] ) ) {
if ( ! empty( $data['billing_first_name'] ) && '' === $customer->get_first_name() ) {
$customer->set_first_name( $data['billing_first_name'] );
}
if ( ! empty( $data['billing_last_name'] ) ) {
if ( ! empty( $data['billing_last_name'] ) && '' === $customer->get_last_name() ) {
$customer->set_last_name( $data['billing_last_name'] );
}
// If the display name is an email, update to the user's full name.
if ( is_email( $customer->get_display_name() ) ) {
$customer->set_display_name( $data['billing_first_name'] . ' ' . $data['billing_last_name'] );
$customer->set_display_name( $customer->get_first_name() . ' ' . $customer->get_last_name() );
}
foreach ( $data as $key => $value ) {

View File

@ -960,12 +960,21 @@ class WC_Countries {
),
),
'JP' => array(
'postcode' => array(
'priority' => 65,
),
'state' => array(
'label' => __( 'Prefecture', 'woocommerce' ),
'priority' => 66,
),
'postcode' => array(
'priority' => 65,
'city' => array(
'priority' => 67,
),
'address_1' => array(
'priority' => 68,
),
'address_2' => array(
'priority' => 69,
),
),
'KR' => array(

View File

@ -144,8 +144,6 @@ class WC_Install {
add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 );
add_filter( 'wpmu_drop_tables', array( __CLASS__, 'wpmu_drop_tables' ) );
add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) );
add_action( 'woocommerce_plugin_background_installer', array( __CLASS__, 'background_installer' ), 10, 2 );
add_action( 'woocommerce_theme_background_installer', array( __CLASS__, 'theme_background_installer' ), 10, 1 );
}
/**
@ -1235,7 +1233,6 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
public static function background_installer( $plugin_to_install_id, $plugin_to_install ) {
// Explicitly clear the event.
$args = func_get_args();
wp_clear_scheduled_hook( 'woocommerce_plugin_background_installer', $args );
if ( ! empty( $plugin_to_install['repo-slug'] ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
@ -1395,7 +1392,6 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
public static function theme_background_installer( $theme_slug ) {
// Explicitly clear the event.
$args = func_get_args();
wp_clear_scheduled_hook( 'woocommerce_theme_background_installer', $args );
if ( ! empty( $theme_slug ) ) {
// Suppress feedback.

View File

@ -109,9 +109,6 @@ class WC_Post_Data {
* @param array $old_tt_ids Old array of term taxonomy IDs.
*/
public static function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
foreach ( array_merge( $tt_ids, $old_tt_ids ) as $id ) {
delete_transient( 'wc_ln_count_' . md5( sanitize_key( $taxonomy ) . sanitize_key( $id ) ) );
}
if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ), true ) ) {
self::delete_product_query_transients();
}
@ -134,23 +131,7 @@ class WC_Post_Data {
* Delete product view transients when needed e.g. when post status changes, or visibility/stock status is modified.
*/
public static function delete_product_query_transients() {
// Increments the transient version to invalidate cache.
WC_Cache_Helper::get_transient_version( 'product_query', true );
// If not using an external caching system, we can clear the transients out manually and avoid filling our DB.
if ( ! wp_using_ext_object_cache() ) {
global $wpdb;
$wpdb->query(
"
DELETE FROM `$wpdb->options`
WHERE `option_name` LIKE ('\_transient\_wc\_uf\_pid\_%')
OR `option_name` LIKE ('\_transient\_timeout\_wc\_uf\_pid\_%')
OR `option_name` LIKE ('\_transient\_wc\_products\_will\_display\_%')
OR `option_name` LIKE ('\_transient\_timeout\_wc\_products\_will\_display\_%')
"
);
}
}
/**

View File

@ -218,7 +218,7 @@ class WC_Regenerate_Images {
if ( $uncropped ) {
$full_size = self::get_full_size_image_dimensions( $attachment_id );
if ( ! $full_size ) {
if ( ! $full_size || ! $full_size['width'] || ! $full_size['height'] ) {
return $image;
}

View File

@ -203,6 +203,11 @@ class WC_Structured_Data {
'name' => $product->get_name(),
);
$markup['image'] = wp_get_attachment_url( $product->get_image_id() );
$markup['description'] = wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) );
$markup['sku'] = $product->get_sku();
$markup['brand'] = '';
if ( apply_filters( 'woocommerce_structured_data_product_limit', is_product_taxonomy() || is_shop() ) ) {
$markup['url'] = $permalink;
@ -210,10 +215,6 @@ class WC_Structured_Data {
return;
}
$markup['image'] = wp_get_attachment_url( $product->get_image_id() );
$markup['description'] = wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) );
$markup['sku'] = $product->get_sku();
if ( '' !== $product->get_price() ) {
if ( $product->is_type( 'variable' ) ) {
$lowest = $product->get_variation_price( 'min', false );

View File

@ -882,11 +882,13 @@ class WC_Tax {
$wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', self::prepare_tax_rate( $tax_rate ) );
$tax_rate_id = $wpdb->insert_id;
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
do_action( 'woocommerce_tax_rate_added', $wpdb->insert_id, $tax_rate );
do_action( 'woocommerce_tax_rate_added', $tax_rate_id, $tax_rate );
return $wpdb->insert_id;
return $tax_rate_id;
}
/**

View File

@ -287,7 +287,7 @@ class WC_Payment_Token_Data_Store extends WC_Data_Store_WP implements WC_Payment
* Should contain the fields token_id, gateway_id, token, user_id, type, is_default.
*
* @since 3.0.0
* @param id $user_id User ID.
* @param int $user_id User ID.
* @return object
*/
public function get_users_default_token( $user_id ) {

View File

@ -201,12 +201,11 @@ class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response {
$this->payment_status_paid_cancelled_order( $order, $posted );
}
$this->payment_complete( $order, ( ! empty( $posted['txn_id'] ) ? wc_clean( $posted['txn_id'] ) : '' ), __( 'IPN payment completed', 'woocommerce' ) );
if ( ! empty( $posted['mc_fee'] ) ) {
// Log paypal transaction fee.
update_post_meta( $order->get_id(), 'PayPal Transaction Fee', wc_clean( $posted['mc_fee'] ) );
$order->add_meta_data( 'PayPal Transaction Fee', wc_clean( $posted['mc_fee'] ) );
}
$this->payment_complete( $order, ( ! empty( $posted['txn_id'] ) ? wc_clean( $posted['txn_id'] ) : '' ), __( 'IPN payment completed', 'woocommerce' ) );
} else {
if ( 'authorization' === $posted['pending_reason'] ) {
$this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) );

View File

@ -89,7 +89,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response {
$order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$status = wc_clean( strtolower( wp_unslash( $_REQUEST['st'] ) ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$amount = wc_clean( wp_unslash( $_REQUEST['amt'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$amount = isset( $_REQUEST['amt'] ) ? wc_clean( wp_unslash( $_REQUEST['amt'] ) ) : 0; // WPCS: input var ok, CSRF ok, sanitization ok.
$transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$order = $this->get_paypal_order( $order_id );
@ -102,8 +102,8 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response {
if ( $transaction_result ) {
WC_Gateway_Paypal::log( 'PDT Transaction Status: ' . wc_print_r( $status, true ) );
update_post_meta( $order->get_id(), '_paypal_status', $status );
update_post_meta( $order->get_id(), '_transaction_id', $transaction );
$order->add_meta_data( '_paypal_status', $status );
$order->set_transaction_id( $transaction );
if ( 'completed' === $status ) {
if ( number_format( $order->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) {
@ -111,15 +111,15 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response {
/* translators: 1: Payment amount */
$this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) );
} else {
$this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) );
// Log paypal transaction fee and payment type.
if ( ! empty( $transaction_result['mc_fee'] ) ) {
update_post_meta( $order->get_id(), 'PayPal Transaction Fee', $transaction_result['mc_fee'] );
$order->add_meta_data( 'PayPal Transaction Fee', wc_clean( $transaction_result['mc_fee'] ) );
}
if ( ! empty( $transaction_result['payment_type'] ) ) {
update_post_meta( $order->get_id(), 'Payment type', $transaction_result['payment_type'] );
$order->add_meta_data( 'Payment type', wc_clean( $transaction_result['payment_type'] ) );
}
$this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) );
}
} else {
if ( 'authorization' === $transaction_result['pending_reason'] ) {

View File

@ -27,7 +27,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
*/
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null ) {
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
throw new Exception( __( 'The ' . __CLASS__ . ' class can only be run within WP CLI.', 'action-scheduler' ) );
throw new Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), __CLASS__ ) );
}
parent::__construct( $store, $monitor, $cleaner );

View File

@ -420,6 +420,7 @@ function wc_scheduled_sales() {
}
do_action( 'wc_after_products_starting_sales', $product_ids );
WC_Cache_Helper::get_transient_version( 'product', true );
delete_transient( 'wc_products_onsale' );
}
@ -848,11 +849,11 @@ function wc_get_product_tax_class_options() {
* @return array
*/
function wc_get_product_stock_status_options() {
return array(
return apply_filters( 'woocommerce_product_stock_status_options', array(
'instock' => __( 'In stock', 'woocommerce' ),
'outofstock' => __( 'Out of stock', 'woocommerce' ),
'onbackorder' => __( 'On backorder', 'woocommerce' ),
);
) );
}
/**

View File

@ -1426,6 +1426,7 @@ function wc_get_gallery_image_html( $attachment_id, $main_image = false ) {
$full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) );
$thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size );
$full_src = wp_get_attachment_image_src( $attachment_id, $full_size );
$alt_text = trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
$image = wp_get_attachment_image(
$attachment_id,
$image_size,
@ -1447,7 +1448,7 @@ function wc_get_gallery_image_html( $attachment_id, $main_image = false ) {
)
);
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_src[0] ) . '">' . $image . '</a></div>';
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" data-thumb-alt="' . esc_attr( $alt_text ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_src[0] ) . '">' . $image . '</a></div>';
}
if ( ! function_exists( 'woocommerce_output_product_data_tabs' ) ) {

View File

@ -32,12 +32,13 @@ if ( ! function_exists( 'wc_create_new_customer' ) ) {
/**
* Create a new customer.
*
* @param string $email Customer email.
* @param string $email Customer email.
* @param string $username Customer username.
* @param string $password Customer password.
* @param array $args List of arguments to pass to `wp_insert_user()`.
* @return int|WP_Error Returns WP_Error on failure, Int (user ID) on success.
*/
function wc_create_new_customer( $email, $username = '', $password = '' ) {
function wc_create_new_customer( $email, $username = '', $password = '', $args = array() ) {
// Check the email address.
if ( empty( $email ) || ! is_email( $email ) ) {
@ -96,11 +97,14 @@ if ( ! function_exists( 'wc_create_new_customer' ) ) {
$new_customer_data = apply_filters(
'woocommerce_new_customer_data',
array(
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'role' => 'customer',
array_merge(
$args,
array(
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'role' => 'customer',
)
)
);
@ -380,9 +384,7 @@ add_filter( 'user_has_cap', 'wc_customer_has_capability', 10, 3 );
function wc_shop_manager_has_capability( $allcaps, $caps, $args, $user ) {
if ( wc_user_has_role( $user, 'shop_manager' ) ) {
/**
* @see wc_modify_map_meta_cap, which limits editing to customers.
*/
// @see wc_modify_map_meta_cap, which limits editing to customers.
$allcaps['edit_users'] = true;
}

40
package-lock.json generated
View File

@ -641,13 +641,13 @@
"dev": true
},
"autoprefixer": {
"version": "9.4.8",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.8.tgz",
"integrity": "sha512-DIhd0KMi9Nql3oJkJ2HCeOVihrXFPtWXc6ckwaUNwliDOt9OGr0fk8vV8jCLWXnZc1EXvQ2uLUzGpcPxFAQHEQ==",
"version": "9.4.9",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.9.tgz",
"integrity": "sha512-OyUl7KvbGBoFQbGQu51hMywz1aaVeud/6uX8r1R1DNcqFvqGUUy6+BDHnAZE8s5t5JyEObaSw+O1DpAdjAmLuw==",
"dev": true,
"requires": {
"browserslist": "^4.4.1",
"caniuse-lite": "^1.0.30000938",
"browserslist": "^4.4.2",
"caniuse-lite": "^1.0.30000939",
"normalize-range": "^0.1.2",
"num2fraction": "^1.2.2",
"postcss": "^7.0.14",
@ -2058,14 +2058,14 @@
"dev": true
},
"browserslist": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz",
"integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==",
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.2.tgz",
"integrity": "sha512-ISS/AIAiHERJ3d45Fz0AVYKkgcy+F/eJHzKEvv1j0wwKGKD9T3BrwKr/5g45L+Y4XIK5PlTqefHciRFcfE1Jxg==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30000929",
"electron-to-chromium": "^1.3.103",
"node-releases": "^1.1.3"
"caniuse-lite": "^1.0.30000939",
"electron-to-chromium": "^1.3.113",
"node-releases": "^1.1.8"
}
},
"buffer-from": {
@ -2166,9 +2166,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30000938",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz",
"integrity": "sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw==",
"version": "1.0.30000939",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000939.tgz",
"integrity": "sha512-oXB23ImDJOgQpGjRv1tCtzAvJr4/OvrHi5SO2vUgB0g0xpdZZoA/BxfImiWfdwoYdUTtQrPsXsvYU/dmCSM8gg==",
"dev": true
},
"caseless": {
@ -5171,9 +5171,9 @@
}
},
"homedir-polyfill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
"integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
"dev": true,
"requires": {
"parse-passwd": "^1.0.0"
@ -7208,9 +7208,9 @@
}
},
"mocha": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.0.tgz",
"integrity": "sha512-A7g9k3yr8oJaXn2IItFnfgjyxFc/LTe6Wwv7FczP+e8G74o9xYNSbMYmCf1ouldRojLrFcOb+z75P6Ak0GX6ug==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz",
"integrity": "sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ==",
"dev": true,
"requires": {
"ansi-colors": "3.2.3",

View File

@ -19,7 +19,7 @@
"git:update-hooks": "rm -r .git/hooks && mkdir -p .git/hooks && node ./node_modules/husky/husky.js install"
},
"devDependencies": {
"autoprefixer": "9.4.8",
"autoprefixer": "9.4.9",
"babel": "6.23.0",
"babel-cli": "6.26.0",
"babel-eslint": "10.0.1",
@ -53,7 +53,7 @@
"husky": "1.3.1",
"istanbul": "1.0.0-alpha.2",
"lint-staged": "8.1.4",
"mocha": "6.0.0",
"mocha": "6.0.2",
"node-sass": "4.11.0",
"prettier": "github:automattic/calypso-prettier#c56b4251",
"stylelint": "9.10.1",

View File

@ -1,8 +1,12 @@
<?php
/**
* Customer functions
*
* @package WooCommerce\Tests\Customer
*/
/**
* Customer functions.
* @package WooCommerce\Tests\Customer
* WC_Tests_Customer_Functions class.
*/
class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
@ -45,6 +49,19 @@ class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
$userdata = get_userdata( $id );
$this->assertEquals( 'fred2', $userdata->user_login );
// Test extra arguments to generate display_name.
$id = wc_create_new_customer(
'john.doe@example.com',
'',
'testpassword',
array(
'first_name' => 'John',
'last_name' => 'Doe',
)
);
$userdata = get_userdata( $id );
$this->assertEquals( 'John Doe', $userdata->display_name );
// No password.
update_option( 'woocommerce_registration_generate_password', 'no' );
$id = wc_create_new_customer( 'joe@example.com', 'joecustomer', '' );
@ -70,7 +87,7 @@ class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
$order2 = new WC_Order();
$order2->save();
// Test download permissions
// Test download permissions.
$prod_download = new WC_Product_Download();
$prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' );
$prod_download->set_id( 'download' );

View File

@ -1028,4 +1028,21 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
unset( $image_attr, $expected_attr );
}
/**
* Test wc_get_product_stock_status_options().
*
* @since 3.6.0
*/
public function test_wc_get_product_stock_status_options() {
$status_options = (array) apply_filters(
'woocommerce_product_stock_status_options', array(
'instock' => 'In stock',
'outofstock' => 'Out of stock',
'onbackorder' => 'On backorder',
)
);
$this->assertEquals( $status_options, wc_get_product_stock_status_options() );
}
}