Add notice about webhooks using the legacy REST API (#40866)

Co-authored-by: Corey McKrill <916023+coreymckrill@users.noreply.github.com>
This commit is contained in:
Néstor Soriano 2023-10-24 08:51:36 +02:00 committed by GitHub
parent 7aea11a7d0
commit 481e799c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 29 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add notices about the webhooks using legacy REST API payload going unsupported in WooCommerce 9.0

View File

@ -9,6 +9,7 @@
use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
use Automattic\WooCommerce\Internal\Utilities\Users;
use Automattic\WooCommerce\Internal\Utilities\WebhookUtil;
defined( 'ABSPATH' ) || exit;
@ -125,53 +126,72 @@ class WC_Admin_Notices {
// phpcs:disable Generic.Commenting.Todo.TaskFound
/**
* Add an admin notice about the removal of the Legacy REST API if the said API is enabled.
* Add an admin notice about the removal of the Legacy REST API if the said API is enabled,
* and a notice about soon to be unsupported webhooks with Legacy API payload if at least one of these exist.
*
* TODO: Change this method in WooCommerce 9.0 so that it checks if the Legacy REST API extension is installed, and if not, it points to the extension URL in the WordPress plugins directory.
*/
private static function maybe_add_legacy_api_removal_notice() {
if ( ! self::must_show_legacy_api_removal_notice() ) {
if ( is_plugin_active( 'woocommerce-legacy-rest-api/woocommerce-legacy-rest-api.php' ) ) {
return;
}
self::add_custom_notice(
'legacy_api_removed_in_woo_90',
sprintf(
'%s%s',
sprintf(
'<h4>%s</h4>',
esc_html__( 'The WooCommerce Legacy REST API will be removed soon', 'woocommerce' )
),
if ( 'yes' === get_option( 'woocommerce_api_enabled' ) ) {
self::add_custom_notice(
'legacy_api_removed_in_woo_90',
sprintf(
'%s%s',
sprintf(
'<h4>%s</h4>',
esc_html__( 'The WooCommerce Legacy REST API will be removed soon', 'woocommerce' )
),
sprintf(
// translators: Placeholders are URLs.
wpautop( wp_kses_data( __( 'The WooCommerce Legacy REST API, <a href="%1$s">currently enabled in this site</a>, will be removed in WooCommerce 9.0. A separate WooCommerce extension will be available to keep it enabled. <b><a target=”_blank” href="%2$s">Learn more about this change.</a></b>', 'woocommerce' ) ) ),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=legacy_api' ),
'https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
wpautop( wp_kses_data( __( 'The WooCommerce Legacy REST API, <a href="%1$s">currently enabled in this site</a>, will be removed in WooCommerce 9.0. A separate WooCommerce extension will be available to keep it enabled. <b><a target=”_blank” href="%2$s">Learn more about this change.</a></b>', 'woocommerce' ) ) ),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=legacy_api' ),
'https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
)
)
)
);
);
}
if ( wc_get_container()->get( WebhookUtil::class )->get_legacy_webhooks_count() > 0 ) {
self::add_custom_notice(
'legacy_webhooks_unsupported_in_woo_90',
sprintf(
'%s%s',
sprintf(
'<h4>%s</h4>',
esc_html__( 'WooCommerce webhooks that use the Legacy REST API will be unsupported soon', 'woocommerce' )
),
sprintf(
// translators: Placeholders are URLs.
wpautop( wp_kses_data( __( 'The WooCommerce Legacy REST API will be removed in WooCommerce 9.0, and this will cause <a href="%1$s">webhooks on this site that are configured to use the Legacy REST API</a> to stop working. A separate WooCommerce extension will be available to allow these webhooks to keep using the Legacy REST API without interruption. You can also edit these webhooks to use the current REST API version to generate the payload instead. <b><a target=”_blank” href="%2$s">Learn more about this change.</a></b>', 'woocommerce' ) ) ),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks&legacy=true' ),
'https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/'
)
)
);
}
}
/**
* Remove the admin notice about the removal of the Legacy REST API if the said API is disabled.
* Remove the admin notice about the removal of the Legacy REST API if the said API is disabled
* or if the Legacy REST API extension is installed, and remove the notice about Legacy webhooks
* if no such webhooks exist anymore or if the Legacy REST API extension is installed.
*
* TODO: Change this method in WooCommerce 9.0 so that the notice gets removed if the Legacy REST API extension is installed and active.
*/
private static function maybe_remove_legacy_api_removal_notice() {
if ( self::has_notice( 'legacy_api_removed_in_woo_90' ) && ! self::must_show_legacy_api_removal_notice() ) {
$plugin_is_active = is_plugin_active( 'woocommerce-legacy-rest-api/woocommerce-legacy-rest-api.php' );
if ( self::has_notice( 'legacy_api_removed_in_woo_90' ) && ( $plugin_is_active || 'yes' !== get_option( 'woocommerce_api_enabled' ) ) ) {
self::remove_notice( 'legacy_api_removed_in_woo_90' );
}
}
/**
* Is it needed to display the legacy API removal notice?
*
* TODO: Change or remove this method in WooCommerce 9.0 accordingly, depending on the changes to maybe_add/remove_legacy_api_removal_notice.
*
* @return bool True if the legacy API removal notice must be displayed.
*/
private static function must_show_legacy_api_removal_notice() {
return 'yes' === get_option( 'woocommerce_api_enabled' ) && ! is_plugin_active( 'woocommerce-legacy-rest-api/woocommerce-legacy-rest-api.php' );
if ( self::has_notice( 'legacy_webhooks_unsupported_in_woo_90' ) && ( $plugin_is_active || 0 === wc_get_container()->get( WebhookUtil::class )->get_legacy_webhooks_count() ) ) {
self::remove_notice( 'legacy_webhooks_unsupported_in_woo_90' );
}
}
// phpcs:enable Generic.Commenting.Todo.TaskFound

View File

@ -6,6 +6,8 @@
* @version 3.3.0
*/
use Automattic\WooCommerce\Internal\Utilities\WebhookUtil;
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WP_List_Table' ) ) {
@ -174,7 +176,8 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
$num_webhooks = $data_store->get_count_webhooks_by_status();
$total_webhooks = array_sum( (array) $num_webhooks );
$statuses = array_keys( wc_get_webhook_statuses() );
$class = empty( $_REQUEST['status'] ) ? ' class="current"' : ''; // WPCS: input var okay. CSRF ok.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$class = empty( $_REQUEST['status'] ) && empty( $_REQUEST['legacy'] ) ? ' class="current"' : '';
/* translators: %s: count */
$status_links['all'] = "<a href='admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_webhooks, 'posts', 'woocommerce' ), number_format_i18n( $total_webhooks ) ) . '</a>';
@ -186,7 +189,8 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
continue;
}
if ( isset( $_REQUEST['status'] ) && sanitize_key( wp_unslash( $_REQUEST['status'] ) ) === $status_name ) { // WPCS: input var okay, CSRF ok.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_REQUEST['status'] ) && sanitize_key( wp_unslash( $_REQUEST['status'] ) ) === $status_name ) {
$class = ' class="current"';
}
@ -195,6 +199,20 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
$status_links[ $status_name ] = "<a href='admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks&amp;status=$status_name'$class>" . sprintf( translate_nooped_plural( $label, $num_webhooks[ $status_name ] ), number_format_i18n( $num_webhooks[ $status_name ] ) ) . '</a>';
}
$legacy_webhooks_count = wc_get_container()->get( WebhookUtil::class )->get_legacy_webhooks_count();
if ( $legacy_webhooks_count > 0 ) {
$class = '';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( 'true' === sanitize_key( wp_unslash( $_REQUEST['legacy'] ?? '' ) ) ) {
$class = ' class="current"';
}
$label = $this->get_status_label( __( 'Legacy', 'woocommerce' ), $legacy_webhooks_count );
$status_links['legacy'] = "<a href='admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks&amp;legacy=true'$class>" . sprintf( translate_nooped_plural( $label, $legacy_webhooks_count ), number_format_i18n( $legacy_webhooks_count ) ) . '</a>';
}
return $status_links;
}
@ -299,6 +317,11 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
$args['paginate'] = true;
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( 'true' === sanitize_key( wp_unslash( $_REQUEST['legacy'] ?? null ) ) ) {
$args['api_version'] = -1;
}
// Get the webhooks.
$data_store = WC_Data_Store::load( 'webhook' );
$webhooks = $data_store->search_webhooks( $args );

View File

@ -283,6 +283,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$date_created = '';
$date_modified = '';
$user_id = '';
$api_version = '';
if ( ! empty( $args['include'] ) ) {
$args['include'] = implode( ',', wp_parse_id_list( $args['include'] ) );
@ -312,6 +313,11 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$date_modified = "AND `date_modified_gmt` BETWEEN STR_TO_DATE('" . esc_sql( $args['modified_after'] ) . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . esc_sql( $args['modified_before'] ) . "', '%Y-%m-%d %H:%i:%s')";
}
$api_version_value = $args['api_version'] ?? null;
if ( is_numeric( $api_version_value ) ) {
$api_version = 'AND `api_version`=' . esc_sql( $api_version_value );
}
// Check for cache.
$cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . 'search_webhooks' . md5( implode( ',', $args ) );
$cache_value = wp_cache_get( $cache_key, 'webhook_search_results' );
@ -331,6 +337,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
{$exclude}
{$date_created}
{$date_modified}
{$api_version}
{$user_id}
{$order}
{$limit}

View File

@ -6,6 +6,7 @@
namespace Automattic\WooCommerce\Internal\Utilities;
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
use WC_Cache_Helper;
/**
* Class with utility methods for dealing with webhooks.
@ -133,4 +134,23 @@ class WebhookUtil {
)
);
}
/**
* Gets the count of webhooks that are configured to use the Legacy REST API to compose their payloads.
*
* @return int
*/
public function get_legacy_webhooks_count(): int {
global $wpdb;
$cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . 'legacy_count';
$count = wp_cache_get( $cache_key, 'webhooks' );
if ( false === $count ) {
$count = absint( $wpdb->get_var( "SELECT count( webhook_id ) FROM {$wpdb->prefix}wc_webhooks WHERE `api_version` < 1;" ) );
wp_cache_add( $cache_key, $count, 'webhooks' );
}
return $count;
}
}