Merge branch feature/marketplace-suggestions into add/product-edit-suggestions
# Conflicts: #assets/css/admin-rtl.css #assets/css/admin.css #assets/css/marketplace-suggestions-rtl.css #assets/css/marketplace-suggestions.css #assets/css/marketplace-suggestions.scss #assets/js/admin/marketplace-suggestions.js #includes/admin/class-wc-admin-assets.php #includes/admin/marketplace-suggestions/class-wc-marketplace-suggestions.php
This commit is contained in:
commit
0dcc87110b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -5921,26 +5921,6 @@ table.bar_chart {
|
||||||
@include icon( "\e01b" );
|
@include icon( "\e01b" );
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-type-product .woocommerce-BlankState {
|
|
||||||
max-width: 764px;
|
|
||||||
text-align: center;
|
|
||||||
margin: auto;
|
|
||||||
|
|
||||||
.woocommerce-BlankState-message {
|
|
||||||
color: #444;
|
|
||||||
font-size: 1.5em;
|
|
||||||
margin: 0 auto 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-BlankState-message::before {
|
|
||||||
font-size: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-BlankState-buttons {
|
|
||||||
margin-bottom: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-BlankState {
|
.woocommerce-BlankState {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 5em 0 0;
|
padding: 5em 0 0;
|
||||||
|
@ -5974,6 +5954,27 @@ table.bar_chart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post-type-product .woocommerce-BlankState,
|
||||||
|
.post-type-shop_order .woocommerce-BlankState {
|
||||||
|
max-width: 764px;
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
.woocommerce-BlankState-message {
|
||||||
|
color: #444;
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0 auto 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-BlankState-message::before {
|
||||||
|
font-size: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-BlankState-buttons {
|
||||||
|
margin-bottom: 4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Small screen optimisation
|
* Small screen optimisation
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -88,7 +88,9 @@ a.suggestion-dismiss::before {
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-header"],
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-header"],
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"],
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"],
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-header"],
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-header"],
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-footer"] {
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-footer"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-header"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-footer"] {
|
||||||
|
|
||||||
.marketplace-suggestion-container {
|
.marketplace-suggestion-container {
|
||||||
|
|
||||||
|
@ -105,7 +107,8 @@ a.suggestion-dismiss::before {
|
||||||
|
|
||||||
// Optimise footer suggestion layout for left-aligned CTA link button only.
|
// Optimise footer suggestion layout for left-aligned CTA link button only.
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"],
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"],
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-footer"] {
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="product-edit-meta-tab-footer"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-footer"] {
|
||||||
|
|
||||||
.marketplace-suggestion-container {
|
.marketplace-suggestion-container {
|
||||||
|
|
||||||
|
@ -181,14 +184,17 @@ a.suggestion-dismiss::before {
|
||||||
}
|
}
|
||||||
|
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-header"],
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-header"],
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"] {
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-footer"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-header"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-footer"] {
|
||||||
|
|
||||||
.marketplace-suggestion-container {
|
.marketplace-suggestion-container {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-body"] {
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="products-list-empty-body"],
|
||||||
|
.marketplace-suggestions-container.showing-suggestion[data-marketplace-suggestions-context="orders-list-empty-body"] {
|
||||||
|
|
||||||
.marketplace-suggestion-container {
|
.marketplace-suggestion-container {
|
||||||
padding: 0.75em 1.5em;
|
padding: 0.75em 1.5em;
|
||||||
|
|
|
@ -53,11 +53,48 @@
|
||||||
return dismissButton;
|
return dismissButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addUTMParameters( context, url ) {
|
||||||
|
var utmParams = {
|
||||||
|
utm_source: 'unknown',
|
||||||
|
utm_campaign: 'marketplacesuggestions',
|
||||||
|
utm_medium: 'product'
|
||||||
|
};
|
||||||
|
var sourceContextMap = {
|
||||||
|
'productstable': [
|
||||||
|
'products-list-inline'
|
||||||
|
],
|
||||||
|
'productsempty': [
|
||||||
|
'products-list-empty-header',
|
||||||
|
'products-list-empty-footer',
|
||||||
|
'products-list-empty-body'
|
||||||
|
],
|
||||||
|
'ordersempty': [
|
||||||
|
'orders-list-empty-header',
|
||||||
|
'orders-list-empty-footer',
|
||||||
|
'orders-list-empty-body'
|
||||||
|
],
|
||||||
|
'editproduct': [
|
||||||
|
'product-edit-meta-tab-header',
|
||||||
|
'product-edit-meta-tab-footer',
|
||||||
|
'product-edit-meta-tab-body'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
var utmSource = _.findKey( sourceContextMap, function( sourceInfo ) {
|
||||||
|
return _.contains( sourceInfo, context );
|
||||||
|
} );
|
||||||
|
if ( utmSource ) {
|
||||||
|
utmParams.utm_source = utmSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url + '?' + jQuery.param( utmParams );
|
||||||
|
}
|
||||||
|
|
||||||
// Render DOM element for suggestion linkout, optionally with button style.
|
// Render DOM element for suggestion linkout, optionally with button style.
|
||||||
function renderLinkout( slug, url, text, isButton ) {
|
function renderLinkout( context, slug, url, text, isButton ) {
|
||||||
var linkoutButton = document.createElement( 'a' );
|
var linkoutButton = document.createElement( 'a' );
|
||||||
|
|
||||||
linkoutButton.setAttribute( 'href', url );
|
var utmUrl = addUTMParameters( context, url );
|
||||||
|
linkoutButton.setAttribute( 'href', utmUrl );
|
||||||
linkoutButton.setAttribute( 'target', 'blank' );
|
linkoutButton.setAttribute( 'target', 'blank' );
|
||||||
linkoutButton.textContent = text;
|
linkoutButton.textContent = text;
|
||||||
|
|
||||||
|
@ -115,12 +152,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render DOM elements for suggestion call-to-action – button or link with dismiss 'x'.
|
// Render DOM elements for suggestion call-to-action – button or link with dismiss 'x'.
|
||||||
function renderSuggestionCTA( slug, url, linkText, linkIsButton, allowDismiss ) {
|
function renderSuggestionCTA( context, slug, url, linkText, linkIsButton, allowDismiss ) {
|
||||||
var right = document.createElement( 'div' );
|
var right = document.createElement( 'div' );
|
||||||
|
|
||||||
right.classList.add( 'marketplace-suggestion-container-cta' );
|
right.classList.add( 'marketplace-suggestion-container-cta' );
|
||||||
if ( url && linkText ) {
|
if ( url && linkText ) {
|
||||||
var linkoutElement = renderLinkout( slug, url, linkText, linkIsButton );
|
var linkoutElement = renderLinkout( context, slug, url, linkText, linkIsButton );
|
||||||
right.appendChild( linkoutElement );
|
right.appendChild( linkoutElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +170,7 @@
|
||||||
|
|
||||||
// Render a "table banner" style suggestion.
|
// Render a "table banner" style suggestion.
|
||||||
// These are used in admin lists, e.g. products list.
|
// These are used in admin lists, e.g. products list.
|
||||||
function renderTableBanner( slug, iconUrl, title, copy, url, buttonText, allowDismiss ) {
|
function renderTableBanner( context, slug, iconUrl, title, copy, url, buttonText, allowDismiss ) {
|
||||||
if ( ! title || ! url ) {
|
if ( ! title || ! url ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +201,7 @@
|
||||||
renderSuggestionContent( slug, title, copy )
|
renderSuggestionContent( slug, title, copy )
|
||||||
);
|
);
|
||||||
container.appendChild(
|
container.appendChild(
|
||||||
renderSuggestionCTA( slug, url, buttonText, true, allowDismiss )
|
renderSuggestionCTA( context, slug, url, buttonText, true, allowDismiss )
|
||||||
);
|
);
|
||||||
|
|
||||||
cell.appendChild( container );
|
cell.appendChild( container );
|
||||||
|
@ -175,7 +212,7 @@
|
||||||
|
|
||||||
// Render a "list item" style suggestion.
|
// Render a "list item" style suggestion.
|
||||||
// These are used in onboarding style contexts, e.g. products list empty state.
|
// These are used in onboarding style contexts, e.g. products list empty state.
|
||||||
function renderListItem( slug, iconUrl, title, copy, url, linkText, linkIsButton, allowDismiss ) {
|
function renderListItem( context, slug, iconUrl, title, copy, url, linkText, linkIsButton, allowDismiss ) {
|
||||||
var container = document.createElement( 'div' );
|
var container = document.createElement( 'div' );
|
||||||
container.classList.add( 'marketplace-suggestion-container' );
|
container.classList.add( 'marketplace-suggestion-container' );
|
||||||
container.dataset.suggestionSlug = slug;
|
container.dataset.suggestionSlug = slug;
|
||||||
|
@ -188,7 +225,7 @@
|
||||||
renderSuggestionContent( slug, title, copy )
|
renderSuggestionContent( slug, title, copy )
|
||||||
);
|
);
|
||||||
container.appendChild(
|
container.appendChild(
|
||||||
renderSuggestionCTA( slug, url, linkText, linkIsButton, allowDismiss )
|
renderSuggestionCTA( context, slug, url, linkText, linkIsButton, allowDismiss )
|
||||||
);
|
);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
|
@ -211,7 +248,7 @@
|
||||||
|
|
||||||
// hide promos for things the user already has installed
|
// hide promos for things the user already has installed
|
||||||
promos = _.filter( promos, function( promo ) {
|
promos = _.filter( promos, function( promo ) {
|
||||||
return ! _.contains( marketplace_suggestions.installed_woo_plugins, promo['hide-if-installed'] );
|
return ! _.contains( marketplace_suggestions.active_plugins, promo['hide-if-installed'] );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// hide promos that are not applicable based on user's installed extensions
|
// hide promos that are not applicable based on user's installed extensions
|
||||||
|
@ -222,7 +259,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the user has any of the prerequisites, show the promo
|
// if the user has any of the prerequisites, show the promo
|
||||||
return ( _.intersection( marketplace_suggestions.installed_woo_plugins, promo['show-if-installed'] ).length > 0 );
|
return ( _.intersection( marketplace_suggestions.active_plugins, promo['show-if-installed'] ).length > 0 );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
return promos;
|
return promos;
|
||||||
|
@ -230,18 +267,23 @@
|
||||||
|
|
||||||
// Show and hide page elements dependent on suggestion state.
|
// Show and hide page elements dependent on suggestion state.
|
||||||
function hidePageElementsForSuggestionState( usedSuggestionsContexts ) {
|
function hidePageElementsForSuggestionState( usedSuggestionsContexts ) {
|
||||||
var showingProductsEmptyStateSuggestions = _.contains( usedSuggestionsContexts, 'products-list-empty-body' );
|
var showingEmptyStateSuggestions = _.intersection(
|
||||||
|
usedSuggestionsContexts,
|
||||||
|
[ 'products-list-empty-body', 'orders-list-empty-body' ]
|
||||||
|
).length > 0;
|
||||||
|
|
||||||
// Streamline onboarding UI if we're in 'empty state' welcome mode.
|
// Streamline onboarding UI if we're in 'empty state' welcome mode.
|
||||||
if ( showingProductsEmptyStateSuggestions ) {
|
if ( showingEmptyStateSuggestions ) {
|
||||||
$( '#screen-meta-links' ).hide();
|
$( '#screen-meta-links' ).hide();
|
||||||
$( '#wpfooter' ).hide();
|
$( '#wpfooter' ).hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the header & footer, they don't make sense without specific promotion content
|
// Hide the header & footer, they don't make sense without specific promotion content
|
||||||
if ( ! showingProductsEmptyStateSuggestions ) {
|
if ( ! showingEmptyStateSuggestions ) {
|
||||||
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="products-list-empty-header"]' ).hide();
|
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="products-list-empty-header"]' ).hide();
|
||||||
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="products-list-empty-footer"]' ).hide();
|
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="products-list-empty-footer"]' ).hide();
|
||||||
|
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="orders-list-empty-header"]' ).hide();
|
||||||
|
$( '.marketplace-suggestions-container[data-marketplace-suggestions-context="orders-list-empty-footer"]' ).hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
var showingProductMetaboxSuggestions = _.contains( usedSuggestionsContexts, 'product-edit-meta-tab-body' );
|
var showingProductMetaboxSuggestions = _.contains( usedSuggestionsContexts, 'product-edit-meta-tab-body' );
|
||||||
|
@ -284,6 +326,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var content = renderListItem(
|
var content = renderListItem(
|
||||||
|
context,
|
||||||
promos[ i ].slug,
|
promos[ i ].slug,
|
||||||
promos[ i ].icon,
|
promos[ i ].icon,
|
||||||
promos[ i ].title,
|
promos[ i ].title,
|
||||||
|
@ -322,6 +365,7 @@
|
||||||
|
|
||||||
// render first promo
|
// render first promo
|
||||||
var content = renderTableBanner(
|
var content = renderTableBanner(
|
||||||
|
context,
|
||||||
promos[ 0 ].slug,
|
promos[ 0 ].slug,
|
||||||
promos[ 0 ].icon,
|
promos[ 0 ].icon,
|
||||||
promos[ 0 ].title,
|
promos[ 0 ].title,
|
||||||
|
|
|
@ -424,7 +424,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( WC_Marketplace_Suggestions::show_suggestions_for_screen( $screen_id ) ) {
|
if ( WC_Marketplace_Suggestions::show_suggestions_for_screen( $screen_id ) ) {
|
||||||
$woo_plugin_slugs = WC_Helper::get_local_woo_plugin_slugs();
|
$active_plugin_slugs = array_map( 'dirname', get_option( 'active_plugins' ) );
|
||||||
wp_register_script(
|
wp_register_script(
|
||||||
'marketplace-suggestions',
|
'marketplace-suggestions',
|
||||||
WC()->plugin_url() . '/assets/js/admin/marketplace-suggestions' . $suffix . '.js',
|
WC()->plugin_url() . '/assets/js/admin/marketplace-suggestions' . $suffix . '.js',
|
||||||
|
@ -437,7 +437,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
|
||||||
'marketplace_suggestions',
|
'marketplace_suggestions',
|
||||||
array(
|
array(
|
||||||
'dismiss_suggestion_nonce' => wp_create_nonce( 'add_dismissed_marketplace_suggestion' ),
|
'dismiss_suggestion_nonce' => wp_create_nonce( 'add_dismissed_marketplace_suggestion' ),
|
||||||
'installed_woo_plugins' => $woo_plugin_slugs,
|
'active_plugins' => $active_plugin_slugs,
|
||||||
'dismissed_suggestions' => WC_Marketplace_Suggestions::get_dismissed_suggestions(),
|
'dismissed_suggestions' => WC_Marketplace_Suggestions::get_dismissed_suggestions(),
|
||||||
'suggestions_data' => WC_Marketplace_Suggestions::get_suggestions_api_data(),
|
'suggestions_data' => WC_Marketplace_Suggestions::get_suggestions_api_data(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -88,6 +88,7 @@ class WC_Admin {
|
||||||
|
|
||||||
// Marketplace suggestions & related REST API.
|
// Marketplace suggestions & related REST API.
|
||||||
include_once dirname( __FILE__ ) . '/marketplace-suggestions/class-wc-marketplace-suggestions.php';
|
include_once dirname( __FILE__ ) . '/marketplace-suggestions/class-wc-marketplace-suggestions.php';
|
||||||
|
include_once dirname( __FILE__ ) . '/marketplace-suggestions/class-wc-marketplace-updater.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1014,11 +1014,6 @@ class WC_Helper {
|
||||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
$woo_plugins = get_transient( 'wc_helper_installed_woo_plugins' );
|
|
||||||
if ( false !== $woo_plugins ) {
|
|
||||||
return $woo_plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
$plugins = get_plugins();
|
$plugins = get_plugins();
|
||||||
$woo_plugins = array();
|
$woo_plugins = array();
|
||||||
|
|
||||||
|
@ -1055,19 +1050,9 @@ class WC_Helper {
|
||||||
$woo_plugins[ $filename ] = $data;
|
$woo_plugins[ $filename ] = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_transient( 'wc_helper_installed_woo_plugins', $woo_plugins, DAY_IN_SECONDS );
|
|
||||||
return $woo_plugins;
|
return $woo_plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain a list of slugs of locally installed Woo extensions.
|
|
||||||
* (Cached for 1 day.)
|
|
||||||
*/
|
|
||||||
public static function get_local_woo_plugin_slugs() {
|
|
||||||
$slugs = wp_list_pluck( self::get_local_woo_plugins(), 'slug' );
|
|
||||||
return array_values( $slugs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get locally installed Woo themes.
|
* Get locally installed Woo themes.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,9 +47,16 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
|
||||||
*/
|
*/
|
||||||
protected function render_blank_state() {
|
protected function render_blank_state() {
|
||||||
echo '<div class="woocommerce-BlankState">';
|
echo '<div class="woocommerce-BlankState">';
|
||||||
|
|
||||||
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'When you receive a new order, it will appear here.', 'woocommerce' ) . '</h2>';
|
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'When you receive a new order, it will appear here.', 'woocommerce' ) . '</h2>';
|
||||||
|
|
||||||
|
echo '<div class="woocommerce-BlankState-buttons">';
|
||||||
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/managing-orders/?utm_source=blankslate&utm_medium=product&utm_content=ordersdoc&utm_campaign=woocommerceplugin">' . esc_html__( 'Learn more about orders', 'woocommerce' ) . '</a>';
|
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/managing-orders/?utm_source=blankslate&utm_medium=product&utm_content=ordersdoc&utm_campaign=woocommerceplugin">' . esc_html__( 'Learn more about orders', 'woocommerce' ) . '</a>';
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
|
|
||||||
|
do_action( 'wc_marketplace_suggestions_orders_empty_state' );
|
||||||
|
|
||||||
|
echo '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* REST API Marketplace suggestions API
|
* Marketplace suggestions
|
||||||
*
|
*
|
||||||
* Handles requests for marketplace suggestions data & rendering
|
* Behaviour for displaying in-context suggestions for marketplace extensions.
|
||||||
* templates for suggestion DOM content.
|
|
||||||
*
|
*
|
||||||
* @package WooCommerce\Classes
|
* @package WooCommerce\Classes
|
||||||
* @since 3.6.0
|
* @since 3.6.0
|
||||||
|
@ -12,7 +11,7 @@
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API Marketplace suggestions API and related logic.
|
* Marketplace suggestions core behaviour.
|
||||||
*/
|
*/
|
||||||
class WC_Marketplace_Suggestions {
|
class WC_Marketplace_Suggestions {
|
||||||
|
|
||||||
|
@ -33,6 +32,7 @@ class WC_Marketplace_Suggestions {
|
||||||
|
|
||||||
// Register hooks for rendering suggestions container markup.
|
// Register hooks for rendering suggestions container markup.
|
||||||
add_action( 'wc_marketplace_suggestions_products_empty_state', array( __CLASS__, 'render_products_list_empty_state' ) );
|
add_action( 'wc_marketplace_suggestions_products_empty_state', array( __CLASS__, 'render_products_list_empty_state' ) );
|
||||||
|
add_action( 'wc_marketplace_suggestions_orders_empty_state', array( __CLASS__, 'render_orders_list_empty_state' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +118,15 @@ class WC_Marketplace_Suggestions {
|
||||||
self::render_suggestions_container( 'products-list-empty-footer' );
|
self::render_suggestions_container( 'products-list-empty-footer' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render suggestions containers in orders list empty state.
|
||||||
|
*/
|
||||||
|
public static function render_orders_list_empty_state() {
|
||||||
|
self::render_suggestions_container( 'orders-list-empty-header' );
|
||||||
|
self::render_suggestions_container( 'orders-list-empty-body' );
|
||||||
|
self::render_suggestions_container( 'orders-list-empty-footer' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a suggestions container element, with the specified context.
|
* Render a suggestions container element, with the specified context.
|
||||||
*
|
*
|
||||||
|
@ -179,31 +188,10 @@ class WC_Marketplace_Suggestions {
|
||||||
* @return array of json API data
|
* @return array of json API data
|
||||||
*/
|
*/
|
||||||
public static function get_suggestions_api_data() {
|
public static function get_suggestions_api_data() {
|
||||||
$suggestion_data = get_transient( 'wc_marketplace_suggestions' );
|
$data = get_option( 'woocommerce_marketplace_suggestions', array() );
|
||||||
if ( false !== $suggestion_data ) {
|
return ! empty( $data['suggestions'] ) ? $data['suggestions'] : array();
|
||||||
return $suggestion_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
$suggestion_data_url = 'https://d3t0oesq8995hv.cloudfront.net/add-ons/marketplace-suggestions.json';
|
|
||||||
$raw_suggestions = wp_remote_get(
|
|
||||||
$suggestion_data_url,
|
|
||||||
array( 'user-agent' => 'WooCommerce Marketplace Suggestions' )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Parse the data to check for any errors.
|
|
||||||
// If it's valid, store structure in transient.
|
|
||||||
if ( ! is_wp_error( $raw_suggestions ) ) {
|
|
||||||
$suggestions = json_decode( wp_remote_retrieve_body( $raw_suggestions ) );
|
|
||||||
if ( $suggestions && is_array( $suggestions ) ) {
|
|
||||||
set_transient( 'wc_marketplace_suggestions', $suggestions, WEEK_IN_SECONDS );
|
|
||||||
return $suggestions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache empty suggestions data to reduce requests if there are any issues with API.
|
|
||||||
set_transient( 'wc_marketplace_suggestions', array(), DAY_IN_SECONDS );
|
|
||||||
return array();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WC_Marketplace_Suggestions::init();
|
WC_Marketplace_Suggestions::init();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Marketplace suggestions updater
|
||||||
|
*
|
||||||
|
* Uses WC_Queue to ensure marketplace suggestions data is up to date and cached locally.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Classes
|
||||||
|
* @since 3.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marketplace Suggestions Updater
|
||||||
|
*/
|
||||||
|
class WC_Marketplace_Updater {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup.
|
||||||
|
*/
|
||||||
|
public static function load() {
|
||||||
|
add_action( 'init', array( __CLASS__, 'init' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule events and hook appropriate actions.
|
||||||
|
*/
|
||||||
|
public static function init() {
|
||||||
|
$queue = WC()->queue();
|
||||||
|
$next = $queue->get_next( 'woocommerce_update_marketplace_suggestions' );
|
||||||
|
if ( ! $next ) {
|
||||||
|
$queue->schedule_recurring( time(), WEEK_IN_SECONDS, 'woocommerce_update_marketplace_suggestions' );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'woocommerce_update_marketplace_suggestions', array( __CLASS__, 'update_marketplace_suggestions' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches new marketplace data, updates wc_marketplace_suggestions.
|
||||||
|
*/
|
||||||
|
public static function update_marketplace_suggestions() {
|
||||||
|
$data = get_option(
|
||||||
|
'woocommerce_marketplace_suggestions',
|
||||||
|
array(
|
||||||
|
'suggestions' => array(),
|
||||||
|
'updated' => time(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$data['updated'] = time();
|
||||||
|
|
||||||
|
$url = 'https://d3t0oesq8995hv.cloudfront.net/add-ons/marketplace-suggestions.json';
|
||||||
|
$request = wp_safe_remote_get( $url );
|
||||||
|
|
||||||
|
if ( is_wp_error( $request ) ) {
|
||||||
|
self::retry();
|
||||||
|
return update_option( 'woocommerce_marketplace_suggestions', $data, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = wp_remote_retrieve_body( $request );
|
||||||
|
if ( empty( $body ) ) {
|
||||||
|
self::retry();
|
||||||
|
return update_option( 'woocommerce_marketplace_suggestions', $data, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = json_decode( $body, true );
|
||||||
|
if ( empty( $body ) || ! is_array( $body ) ) {
|
||||||
|
self::retry();
|
||||||
|
return update_option( 'woocommerce_marketplace_suggestions', $data, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['suggestions'] = $body;
|
||||||
|
return update_option( 'woocommerce_marketplace_suggestions', $data, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when an error has occured when fetching suggestions.
|
||||||
|
* Re-schedules the job earlier than the main weekly one.
|
||||||
|
*/
|
||||||
|
public static function retry() {
|
||||||
|
WC()->queue()->cancel( 'woocommerce_update_marketplace_suggestions' );
|
||||||
|
WC()->queue()->schedule_single( time() + DAY_IN_SECONDS, 'woocommerce_update_marketplace_suggestions' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WC_Marketplace_Updater::load();
|
|
@ -372,6 +372,7 @@ final class WooCommerce {
|
||||||
include_once WC_ABSPATH . 'includes/class-wc-logger.php';
|
include_once WC_ABSPATH . 'includes/class-wc-logger.php';
|
||||||
include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php';
|
include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php';
|
||||||
include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php';
|
include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php';
|
||||||
|
include_once WC_ABSPATH . 'includes/admin/marketplace-suggestions/class-wc-marketplace-updater.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data stores - used to store and retrieve CRUD object data from the database.
|
* Data stores - used to store and retrieve CRUD object data from the database.
|
||||||
|
|
Loading…
Reference in New Issue