Merge branch 'trunk' of https://github.com/woocommerce/woocommerce into fix/update-api-tests-package-lock

This commit is contained in:
Greg 2021-10-13 13:48:34 -06:00
commit 4684b1fdd2
6 changed files with 247 additions and 27 deletions

View File

@ -1,5 +1,78 @@
== Changelog ==
= 5.8.0 2021-10-12 =
**WooCommerce**
* Add - `modified_before` and `modified_after` filtering parameters to REST API for products, orders and coupons. #30585
* Add - `woocommerce_quantity_input_min_admin` and `woocommerce_quantity_input_step_admin` filters. #30705
* Dev - Action Scheduler updated to 3.3.0. #30719
* Dev - Add order argument to `woocommerce_order_actions` filter. #30475
* Fix - During product quick edit, the featured setting is sometimes not shown correctly as checked. #30639
* Fix - Offsets not calculated correctly sometimes on select2 dropdowns causing usability issues. #30690
* Fix - Select2 dropdown search input not getting focus when select2 dropdown element gets focused. #30626
* Tweak - Add individual item remove notices based on the context of the line item in the order. #30650
* Tweak - Change the shop page summary which was not relevant to the public. #30573
* Tweak - Deleted unneeded double spaces in text strings. #30487
* Tweak - Open Browse all extensions link in a new tab. #30640
** WooCommerce Admin - 2.7.1 & 2.7.2**
* Fix - Fix analytics crashing on daylight saving. #7763
* Fix - Allow super admins all capabilities within WooCommerce Admin. #7489
* Fix - Fix end date for last periods. #6584
* Fix - Fix up onboarding profiler not working when opted out of tracking. #7490
* Fix - Making Business Details sticky in onboarding wizard. #7426
* Fix - Missing RTL for onboarding styles. #7531
* Fix - Skip scheduling action if Action Scheduler tables have not been set up. #7521
* Fix - Update country region typeahead for better autofill support. #7497
* Fix - Use installable extensions for local state versus free extensions. #7585
* Fix - Fix fatal error and unrelated results in analytics. #7682
* Fix - Harden the reports directory. #7691
* Fix - Update task-item logic to only display content when expanded is true. #7611
* Add - Show Pinterest in installed marketing extensions (if installed). #7417
* Add - Added MailchimpScheduler that runs daily to subscribe store_email in the profile data. #7579
* Add - Added shipping plugin recommendations to settings page. #7446
* Add - Adding endpoint to snooze onboarding task. #7539
* Add - Adding undo snooze task endpoint. #7560
* Add - Add task dismissal endpoints. #7538
* Update - Add HK and SG countries to WC Pay intl support. #7558
* Update - Create task list REST API endpoint. #7512
* Update - Deleted OnboardingEmailMarketing note class. #7595
* Update - Removes the use of the depreciated woocommerce_shared_settings hook. #7480
* Update - Removes non WooCommerce Admin specific settings from the `wc_admin` namespace in the `wc/data` settings store (ex: countries). #7480
* Update - Updating eway logo in payment suggestions defaults. #7562
* Update - Update marketing task completion logic. #7586
* Dev - Add email address field to OBW. #7552
* Tweak - Add navigation items for the Marketplace menu. #7529
* Tweak - Change all analytics strings and labels to sentence case. #6501
* Tweak - Delete unneeded double spaces in text strings. #7502
* Tweak - Remove the preloaded onboarding options. #7338
* Tweak - Update analytics card header text styles. #6506
* Enhancement - Align Table fields with the fallback on isNumeric. #7431
**WooCommerce Blocks - 5.7.1 & 5.8.0 & 5.9.0 & 5.9.1**
* Add - Extensibility point for extensions to filter payment methods. #4668
* Add - "Filter Products by Stock" block. #4145
* Add - Introduced the `__experimental_woocommerce_blocks_checkout_update_order_from_request` hook to the Checkout Store API. #4610.
* Fix - Add label element to `<BlockTitle>` component. #4585
* Fix - Disable Cart, Checkout, All Products & filters blocks from the widgets screen.
* Fix - Infinite recursion when removing an attribute filter from the Active filters block. #4816
* Fix - Prevent Product Category List from displaying incorrectly when used on the shop page. #4587
* Fix - Product Search block displaying incorrectly. #4740
* Tweak - Add Extensibility info to Store API readme. #4605
* Tweak - Update documentation for the snackbarNoticeVisibility filter. #4508
* Tweak - Add documentation for `extensionCartUpdate` method - this allows extensions to update the client-side cart after it has been modified on the server. #4377
**Action Scheduler 3.3.0**
* Enhancement - Adds as_has_scheduled_action() to provide a performant way to test for existing actions. #645
* Dev - Now supports queries that use multiple statuses. #649
* Dev - Minimum requirements for WordPress and PHP bumped (to 5.2 and 5.6 respectively). #723
* Fix - Improves compatibility with environments where NO_ZERO_DATE is enabled. #519
* Fix - Adds safety checks to guard against errors when our database tables cannot be created. #645
= 5.7.1 2021-09-23 =
**WooCommerce**

View File

@ -7,6 +7,7 @@
*/
use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Admin\RemoteInboxNotifications as PromotionRuleEngine;
if ( ! defined( 'ABSPATH' ) ) {
exit;
@ -81,10 +82,10 @@ class WC_Admin_Addons {
* @param string $term Search terms.
* @param string $country Store country.
*
* @return array of extensions
* @return object of extensions and promotions.
*/
public static function get_extension_data( $category, $term, $country ) {
$parameters = self::build_parameter_string( $category, $term, $country );
$parameters = self::build_parameter_string( $category, $term, $country );
$headers = array();
$auth = WC_Helper_Options::get( 'auth' );
@ -99,7 +100,7 @@ class WC_Admin_Addons {
);
if ( ! is_wp_error( $raw_extensions ) ) {
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) )->products;
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) );
}
return $addons;
}
@ -522,6 +523,37 @@ class WC_Admin_Addons {
<?php
}
/**
* Output the HTML for the promotion block.
*
* @param array $promotion Array of promotion block data.
* @return void
*/
public static function output_search_promotion_block( array $promotion ) {
?>
<div class="addons-wcs-banner-block">
<div class="addons-wcs-banner-block-image">
<img
class="addons-img"
src="<?php echo esc_url( $promotion['image'] ); ?>"
alt="<?php echo esc_attr( $promotion['image_alt'] ); ?>"
/>
</div>
<div class="addons-wcs-banner-block-content">
<h1><?php echo esc_html( $promotion['title'] ); ?></h1>
<p><?php echo esc_html( $promotion['description'] ); ?></p>
<?php
if ( ! empty( $promotion['actions'] ) ) {
foreach ( $promotion['actions'] as $action ) {
self::output_promotion_action( $action );
}
}
?>
</div>
</div>
<?php
}
/**
* Handles the output of a full-width block.
*
@ -563,7 +595,6 @@ class WC_Admin_Addons {
</div>
<div class="addons-promotion-block-buttons">
<?php
if ( $section['button_1'] ) {
self::output_button(
$section['button_1_href'],
@ -581,7 +612,6 @@ class WC_Admin_Addons {
$section['plugin']
);
}
?>
</div>
</div>
@ -680,6 +710,26 @@ class WC_Admin_Addons {
<?php
}
/**
* Output HTML for a promotion action.
*
* @param array $action Array of action properties.
* @return void
*/
public static function output_promotion_action( array $action ) {
if ( empty( $action ) ) {
return;
}
$style = ( ! empty( $action['primary'] ) && $action['primary'] ) ? 'addons-button-solid' : 'addons-button-outline-purple';
?>
<a
class="addons-button <?php echo esc_attr( $style ); ?>"
href="<?php echo esc_url( $action['url'] ); ?>">
<?php echo esc_html( $action['label'] ); ?>
</a>
<?php
}
/**
* Handles output of the addons page in admin.
@ -710,13 +760,33 @@ class WC_Admin_Addons {
$sections = self::get_sections();
$theme = wp_get_theme();
$current_section = isset( $_GET['section'] ) ? $section : '_featured';
$promotions = array();
$addons = array();
if ( '_featured' !== $current_section ) {
$category = $section ? $section : null;
$term = $search ? $search : null;
$country = WC()->countries->get_base_country();
$addons = self::get_extension_data( $category, $term, $country );
$category = $section ? $section : null;
$term = $search ? $search : null;
$country = WC()->countries->get_base_country();
$extension_data = self::get_extension_data( $category, $term, $country );
$addons = $extension_data->products;
$promotions = ! empty( $extension_data->promotions ) ? $extension_data->promotions : array();
}
// We need Automattic\WooCommerce\Admin\RemoteInboxNotifications for the next part, if not remove all promotions.
if ( ! WC()->is_wc_admin_active() ) {
$promotions = array();
}
// Check for existence of promotions and evaluate out if we should show them.
if ( ! empty( $promotions ) ) {
foreach ( $promotions as $promo_id => $promotion ) {
$evaluator = new PromotionRuleEngine\RuleEvaluator();
$passed = $evaluator->evaluate( $promotion->rules );
if ( ! $passed ) {
unset( $promotions[ $promo_id ] );
}
}
// Transform promotions to the correct format ready for output.
$promotions = self::format_promotions( $promotions );
}
/**
@ -811,4 +881,73 @@ class WC_Admin_Addons {
return " $admin_body_class woocommerce-page-wc-marketplace ";
}
/**
* Take an action object and return the URL based on properties of the action.
*
* @param object $action Action object.
* @return string URL.
*/
public static function get_action_url( $action ): string {
if ( ! isset( $action->url ) ) {
return '';
}
if ( isset( $action->url_is_admin_query ) && $action->url_is_admin_query ) {
return wc_admin_url( $action->url );
}
if ( isset( $action->url_is_admin_nonce_query ) && $action->url_is_admin_nonce_query ) {
if ( empty( $action->nonce ) ) {
return '';
}
return wp_nonce_url(
admin_url( $action->url ),
$action->nonce
);
}
return $action->url;
}
/**
* Format the promotion data ready for display, ie fetch locales and actions.
*
* @param array $promotions Array of promotoin objects.
* @return array Array of formatted promotions ready for output.
*/
public static function format_promotions( array $promotions ): array {
$formatted_promotions = array();
foreach ( $promotions as $promotion ) {
// Get the matching locale or fall back to en-US.
$locale = PromotionRuleEngine\SpecRunner::get_locale( $promotion->locales );
if ( null === $locale ) {
continue;
}
$promotion_actions = array();
if ( ! empty( $promotion->actions ) ) {
foreach ( $promotion->actions as $action ) {
$action_locale = PromotionRuleEngine\SpecRunner::get_action_locale( $action->locales );
$url = self::get_action_url( $action );
$promotion_actions[] = array(
'name' => $action->name,
'label' => $action_locale->label,
'url' => $url,
'primary' => isset( $action->is_primary ) ? $action->is_primary : false,
);
}
}
$formatted_promotions[] = array(
'title' => $locale->title,
'description' => $locale->description,
'image' => ( 'http' === substr( $locale->image, 0, 4 ) ) ? $locale->image : WC()->plugin_url() . $locale->image,
'image_alt' => $locale->image_alt,
'actions' => $promotion_actions,
);
}
return $formatted_promotions;
}
}

View File

@ -5,8 +5,11 @@
* @package WooCommerce\Admin
* @var string $view
* @var object $addons
* @var object $promotions
*/
use Automattic\WooCommerce\Admin\RemoteInboxNotifications as PromotionRuleEngine;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -62,7 +65,12 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
<div class="wrap">
<div class="marketplace-content-wrapper">
<?php if ( ! empty( $search ) ) : ?>
<?php if ( count( $addons ) == 0 ) : ?>
<h1 class="search-form-title">
<?php esc_html_e( 'Sorry, could not find anything. Try searching again using a different term.', 'woocommerce' ); ?></p>
</h1>
<?php endif; ?>
<?php if ( ! empty( $search ) && count( $addons ) > 0 ) : ?>
<h1 class="search-form-title">
<?php // translators: search keyword. ?>
<?php printf( esc_html__( 'Search results for "%s"', 'woocommerce' ), esc_html( sanitize_text_field( wp_unslash( $search ) ) ) ); ?>
@ -77,16 +85,13 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
</div>
<?php endif; ?>
<?php if ( '_featured' !== $current_section && $addons ) : ?>
<?php if ( 'shipping_methods' === $current_section ) : ?>
<div class="addons-shipping-methods">
<?php WC_Admin_Addons::output_wcs_banner_block(); ?>
</div>
<?php endif; ?>
<?php if ( 'payment-gateways' === $current_section ) : ?>
<div class="addons-shipping-methods">
<?php WC_Admin_Addons::output_wcpay_banner_block(); ?>
</div>
<?php endif; ?>
<?php
if ( ! empty( $promotions ) && WC()->is_wc_admin_active() ) {
foreach ( $promotions as $promotion ) {
WC_Admin_Addons::output_search_promotion_block( $promotion );
}
}
?>
<ul class="products">
<?php foreach ( $addons as $addon ) : ?>
<?php

View File

@ -915,6 +915,12 @@ add_action( 'woocommerce_order_status_cancelled', 'wc_update_coupon_usage_counts
function wc_cancel_unpaid_orders() {
$held_duration = get_option( 'woocommerce_hold_stock_minutes' );
// Re-schedule the event before cancelling orders
// this way in case of a DB timeout or (plugin) crash the event is always scheduled for retry.
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );
wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) {
return;
}
@ -931,9 +937,6 @@ function wc_cancel_unpaid_orders() {
}
}
}
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );
wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
add_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );

View File

@ -4,7 +4,7 @@ Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, d
Requires at least: 5.6
Tested up to: 5.8
Requires PHP: 7.0
Stable tag: 5.7.1
Stable tag: 5.8.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

View File

@ -4494,9 +4494,9 @@
"dev": true
},
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true
},
"to-fast-properties": {