Merge pull request #31126 from woocommerce/update/fallback-extensions-message

Show fallback message in extensions marketplace when the store can't connect to the WCCOM API
This commit is contained in:
Peter Fabian 2021-11-22 11:02:32 +01:00 committed by GitHub
commit 5cba6b6eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 173 additions and 48 deletions

View File

@ -7733,6 +7733,22 @@ table.bar_chart {
font-weight: bold;
}
.wc-addons__empty {
margin: 48px auto;
max-width: 640px;
h2 {
font-size: 20px;
font-weight: 400;
line-height: 1.2;
}
p {
font-size: 16px;
line-height: 1.5;
}
}
@media screen and (min-width: 600px) {
.wc-addons-wrap {

View File

@ -87,17 +87,57 @@ class WC_Admin_Addons {
)
);
if ( ! is_wp_error( $raw_featured ) ) {
$featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
if ( $featured ) {
set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
}
if ( is_wp_error( $raw_featured ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $raw_featured->get_error_message() );
$message = self::is_ssl_error( $raw_featured->get_error_message() )
? __( 'We encountered an SSL error. Please ensure your site supports TLS version 1.2 or above.', 'woocommerce' )
: $raw_featured->get_error_message();
self::output_empty( $message );
return;
}
$response_code = (int) wp_remote_retrieve_response_code( $raw_featured );
if ( 200 !== $response_code ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $response_code );
/* translators: %d: HTTP error code. */
$message = sprintf(
esc_html(
__(
'Our request to the featured API got error code %d.',
'woocommerce'
)
),
$response_code
);
self::output_empty( $message );
return;
}
$featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
if ( empty( $featured ) || ! is_array( $featured ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', 'Empty or malformed response' );
$message = __( 'Our request to the featured API got a malformed response.', 'woocommerce' );
self::output_empty( $message );
return;
}
if ( $featured ) {
set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
}
}
if ( ! empty( $featured ) ) {
self::output_featured( $featured );
}
self::output_featured( $featured );
}
public static function is_ssl_error( $error_message ) {
return false !== stripos( $error_message, 'cURL error 35' );
}
/**
@ -127,7 +167,7 @@ class WC_Admin_Addons {
* @param string $term Search terms.
* @param string $country Store country.
*
* @return object of extensions and promotions.
* @return object|WP_Error Object with products and promotions properties, or WP_Error
*/
public static function get_extension_data( $category, $term, $country ) {
$parameters = self::build_parameter_string( $category, $term, $country );
@ -144,9 +184,24 @@ class WC_Admin_Addons {
array( 'headers' => $headers )
);
if ( ! is_wp_error( $raw_extensions ) ) {
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) );
if ( is_wp_error( $raw_extensions ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $raw_extensions->get_error_message() );
return $raw_extensions;
}
$response_code = (int) wp_remote_retrieve_response_code( $raw_extensions );
if ( 200 !== $response_code ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $response_code );
return new WP_Error( 'error', __( "Our request to the search API got response code $response_code.", 'woocommerce' ) );
}
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) );
if ( ! is_object( $addons ) || ! isset( $addons->products ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', 'Empty or malformed response' );
return new WP_Error( 'error', __( "Our request to the search API got a malformed response.", 'woocommerce' ) );
}
return $addons;
}
@ -908,6 +963,31 @@ class WC_Admin_Addons {
<?php
}
public static function output_empty( $message = '' ) {
?>
<div class="wc-addons__empty">
<h2><?php echo wp_kses_post( __( 'Oh no! We\'re having trouble connecting to the extensions catalog right now.', 'woocommerce' ) ); ?></h2>
<?php if ( ! empty( $message ) ) : ?>
<p><?php echo esc_html( $message ); ?></p>
<?php endif; ?>
<p>
<?php
/* translators: a url */
printf(
wp_kses_post(
__(
'To start growing your business, head over to <a href="%s">WooCommerce.com</a>, where you\'ll find the most popular WooCommerce extensions.',
'woocommerce'
)
),
'https://woocommerce.com/products/?utm_source=extensionsscreen&utm_medium=product&utm_campaign=connectionerror'
);
?>
</p>
</div>
<?php
}
/**
* Handles output of the addons page in admin.
@ -946,7 +1026,7 @@ class WC_Admin_Addons {
$term = $search ? $search : null;
$country = WC()->countries->get_base_country();
$extension_data = self::get_extension_data( $category, $term, $country );
$addons = $extension_data->products;
$addons = is_wp_error( $extension_data ) ? $extension_data : $extension_data->products;
$promotions = ! empty( $extension_data->promotions ) ? $extension_data->promotions : array();
}

View File

@ -70,12 +70,12 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
<div class="wrap">
<div class="marketplace-content-wrapper">
<?php require __DIR__ . '/html-admin-page-addons-category-nav.php'; ?>
<?php if ( ! empty( $search ) && 0 === count( $addons ) ) : ?>
<?php if ( ! empty( $search ) && ! is_wp_error( $addons ) && 0 === count( $addons ) ) : ?>
<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 ) : ?>
<?php if ( ! empty( $search ) && ! is_wp_error( $addons ) && 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 ) ) ) ); ?>
@ -87,42 +87,46 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
<?php WC_Admin_Addons::render_featured(); ?>
</div>
<?php endif; ?>
<?php if ( '_featured' !== $current_section && $addons ) : ?>
<?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
if ( 'shipping_methods' === $current_section ) {
// Do not show USPS or Canada Post extensions for US and CA stores, respectively.
$country = WC()->countries->get_base_country();
if ( 'US' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/usps-shipping-method'
)
) {
continue;
}
if ( 'CA' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/canada-post-shipping-method'
)
) {
continue;
}
<?php if ( '_featured' !== $current_section ) : ?>
<?php if ( is_wp_error( $addons ) ) : ?>
<?php WC_Admin_Addons::output_empty( $addons->get_error_message() ); ?>
<?php else: ?>
<?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
if ( 'shipping_methods' === $current_section ) {
// Do not show USPS or Canada Post extensions for US and CA stores, respectively.
$country = WC()->countries->get_base_country();
if ( 'US' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/usps-shipping-method'
)
) {
continue;
}
if ( 'CA' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/canada-post-shipping-method'
)
) {
continue;
}
}
WC_Admin_Addons::render_product_card( $addon );
?>
<?php endforeach; ?>
</ul>
WC_Admin_Addons::render_product_card( $addon );
?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php endif; ?>
</div>
<?php else : ?>

View File

@ -68,6 +68,7 @@ class WC_Tracks {
/**
* Record an event in Tracks - this is the preferred way to record events from PHP.
* Note: the event request won't be made if $properties has a member called `error`.
*
* @param string $event_name The name of the event.
* @param array $properties Custom properties to send with the event.

View File

@ -22,6 +22,7 @@ class WC_Extensions_Tracking {
add_action( 'woocommerce_helper_disconnected', array( $this, 'track_helper_disconnected' ) );
add_action( 'woocommerce_helper_subscriptions_refresh', array( $this, 'track_helper_subscriptions_refresh' ) );
add_action( 'woocommerce_addon_installed', array( $this, 'track_addon_install' ), 10, 2 );
add_action( 'woocommerce_page_wc-addons_connection_error', array( $this, 'track_extensions_page_connection_error' ), 10, 1 );
}
/**
@ -47,6 +48,29 @@ class WC_Extensions_Tracking {
WC_Tracks::record_event( $event, $properties );
}
/**
* Send a Tracks event when the Extensions page gets a bad response or no response
* from the WCCOM extensions API.
*
* @param string $error
*/
public function track_extensions_page_connection_error( string $error = '' ) {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$properties = array(
'section' => empty( $_REQUEST['section'] ) ? '_featured' : wc_clean( wp_unslash( $_REQUEST['section'] ) ),
);
if ( ! empty( $_REQUEST['search'] ) ) {
$properties['search_term'] = wc_clean( wp_unslash( $_REQUEST['search'] ) );
}
// phpcs:enable
if ( ! empty( $error ) ) {
$properties['error_data'] = $error;
}
WC_Tracks::record_event( 'extensions_view_connection_error', $properties );
}
/**
* Send a Tracks even when a Helper connection process is initiated.
*/