* Plugins DataStore: decouple from onboarding (https://github.com/woocommerce/woocommerce-admin/pull/4048)

* Plugins DataStore: Add client side store

* change active_plugins to public static function

* don't change shape of allowed plugins
This commit is contained in:
Paul Sealock 2020-04-20 14:04:13 +12:00 committed by GitHub
parent bceb25ba0f
commit 28c85668fb
14 changed files with 70 additions and 66 deletions

View File

@ -66,7 +66,7 @@ class Connect extends Component {
async request() {
try {
const connectResponse = await apiFetch( {
path: `${ WC_ADMIN_NAMESPACE }/onboarding/plugins/request-wccom-connect`,
path: `${ WC_ADMIN_NAMESPACE }/plugins/request-wccom-connect`,
method: 'POST',
} );
if ( connectResponse && connectResponse.connectAction ) {
@ -83,7 +83,7 @@ class Connect extends Component {
const { query } = this.props;
try {
const connectResponse = await apiFetch( {
path: `${ WC_ADMIN_NAMESPACE }/onboarding/plugins/finish-wccom-connect`,
path: `${ WC_ADMIN_NAMESPACE }/plugins/finish-wccom-connect`,
method: 'POST',
data: {
request_token: query.request_token,

View File

@ -86,7 +86,7 @@ class PayPal extends Component {
this.setState( { isPending: true } );
try {
const result = await apiFetch( {
path: WC_ADMIN_NAMESPACE + '/onboarding/plugins/connect-paypal',
path: WC_ADMIN_NAMESPACE + '/plugins/connect-paypal',
method: 'POST',
} );
if ( ! result || ! result.connectUrl ) {

View File

@ -73,7 +73,7 @@ class Square extends Component {
}
const result = await apiFetch( {
path: WC_ADMIN_NAMESPACE + '/onboarding/plugins/connect-square',
path: WC_ADMIN_NAMESPACE + '/plugins/connect-square',
method: 'POST',
} );

View File

@ -64,7 +64,7 @@ class WCPay extends Component {
try {
// Fetch the business verification (connect) URL (Stripe KYC) from the backend
const result = await apiFetch( {
path: WC_ADMIN_NAMESPACE + '/onboarding/plugins/connect-wcpay',
path: WC_ADMIN_NAMESPACE + '/plugins/connect-wcpay',
method: 'POST',
} );

View File

@ -15,16 +15,16 @@ To enable the new onboarding experience manually, log-in to `wp-admin`, and go t
## New REST API endpoints
To power the new onboarding flow client side, new REST API endpoints have been introduced. These are purpose built endpoints that exist under the `/wc-admin/onboarding/` namespace, and are not meant to be shipped in the core rest API package. The source is stored in `src/API/OnboardingPlugins.php`, `src/API/OnboardingProfile.php`, and `src/API/OnboardingTasks.php` respectively.
To power the new onboarding flow client side, new REST API endpoints have been introduced. These are purpose built endpoints that exist under the `/wc-admin/onboarding/` namespace, and are not meant to be shipped in the core rest API package. The source is stored in `src/API/Plugins.php`, `src/API/OnboardingProfile.php`, and `src/API/OnboardingTasks.php` respectively.
* POST `/wc-admin/onboarding/plugins/install` - Installs a requested plugin, if present in the `woocommerce_admin_onboarding_plugins_whitelist` array.
* GET `/wc-admin/onboarding/plugins/active` - Returns a list of the currently active plugins.
* POST `/wc-admin/onboarding/plugins/activate` - Activates the requested plugins, if present in the `woocommerce_admin_onboarding_plugins_whitelist` array. Multiple plugins can be passed to activate at once.
* GET `/wc-admin/onboarding/plugins/connect-jetpack` - Generates a URL for connecting to Jetpack. A `redirect_url` is accepted, which is used upon a successful connection.
* POST `/wc-admin/onboarding/plugins/request-wccom-connect` - Generates a URL for the WooCommerce.com connection process.
* POST `/wc-admin/onboarding/plugins/finish-wccom-connect` - Finishes the WooCommerce.com connection process by storing the received access token.
* POST `/wc-admin/onboarding/plugins/connect-paypal` - Generates a URL for connecting to PayPal during the payments task.
* POST `/wc-admin/onboarding/plugins/connect-square` - Generates a URL for connecting to Square during the payments task.
* POST `/wc-admin/plugins/install` - Installs a requested plugin, if present in the `woocommerce_admin_plugins_whitelist` array.
* GET `/wc-admin/plugins/active` - Returns a list of the currently active plugins.
* POST `/wc-admin/plugins/activate` - Activates the requested plugins, if present in the `woocommerce_admin_plugins_whitelist` array. Multiple plugins can be passed to activate at once.
* GET `/wc-admin/plugins/connect-jetpack` - Generates a URL for connecting to Jetpack. A `redirect_url` is accepted, which is used upon a successful connection.
* POST `/wc-admin/plugins/request-wccom-connect` - Generates a URL for the WooCommerce.com connection process.
* POST `/wc-admin/plugins/finish-wccom-connect` - Finishes the WooCommerce.com connection process by storing the received access token.
* POST `/wc-admin/plugins/connect-paypal` - Generates a URL for connecting to PayPal during the payments task.
* POST `/wc-admin/plugins/connect-square` - Generates a URL for connecting to Square during the payments task.
* GET `/wc-admin/onboarding/profile` - Returns the information gathered during the profile wizard. See the `woocommerce_onboarding_profile_properties` array for a list of fields.
* POST `/wc-admin/onboarding/profile` - Sets data for the profile wizard. See the `woocommerce_onboarding_profile_properties` array for a list of fields.
* POST `/wc-admin/onboarding/tasks/import_sample_products` - Used for importing sample products during the appearance task.
@ -66,7 +66,7 @@ We also use existing options from WooCommerce Core or extensions like WooCommerc
During the profile wizard, merchants can select paid product type extensions (like WooCommerce Memberships) or a paid theme. To make installation easier and to finish purchasing, it is necessary to make a [WooCommerce.com connection](https://docs.woocommerce.com/document/managing-woocommerce-com-subscriptions/). We also prompt users to connect on the task list if they chose extensions in the profile wizard, but did not finish connecting.
To make the connection from the new onboarding experience possible, we build our own connection endpoints [/wc-admin/onboarding/plugins/request-wccom-connect](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L298-L355) and [/wc-admin/onboarding/plugins/finish-wccom-connect](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L357-L417).
To make the connection from the new onboarding experience possible, we build our own connection endpoints [/wc-admin/plugins/request-wccom-connect](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L298-L355) and [/wc-admin/plugins/finish-wccom-connect](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L357-L417).
Both of these endpoints use WooCommerce Core's `WC_Helper_API` directly. The main difference with our connection (compared to the connection on the subscriptions page) is the addition of two additional query string parameters:
@ -79,7 +79,7 @@ To disconnect from WooCommerce.com, go to `WooCommerce > Extensions > WooCommerc
Using Jetpack & WooCommerce Services allows us to offer additional features to new WooCommerce users as well as simplify parts of the setup process. For example, we can do automated tax calculations for certain countries, significantly simplifying the tax task. To make this work, the user needs to be connected to a WordPress.com account. This also means development and testing of these features needs to be done on a Jetpack connected site. Search the MGS & the Feld Guide for additional resources on testing Jetpack with local setups.
We have a special Jetpack connection flow designed specifically for WooCommerce onboarding, so that the user feels that they are connecting as part of a cohesive experience. To access this flow, we have a custom Jetpack connection endpoint [/wc-admin/onboarding/plugins/connect-jetpack](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L273-L296).
We have a special Jetpack connection flow designed specifically for WooCommerce onboarding, so that the user feels that they are connecting as part of a cohesive experience. To access this flow, we have a custom Jetpack connection endpoint [/wc-admin/plugins/connect-jetpack](https://github.com/woocommerce/woocommerce-admin/blob/61b771c2643c24334ea062ab3521073beaf50019/src/API/OnboardingPlugins.php#L273-L296).
We use Jetpack's `build_connect_url` function directly, but add the following two query parameters:

View File

@ -94,7 +94,7 @@ export function* installPlugin( plugin ) {
try {
const results = yield apiFetch( {
path: `${ WC_ADMIN_NAMESPACE }/onboarding/plugins/install`,
path: `${ WC_ADMIN_NAMESPACE }/plugins/install`,
method: 'POST',
data: { plugin },
} );
@ -117,7 +117,7 @@ export function* activatePlugins( plugins ) {
try {
const results = yield apiFetch( {
path: `${ WC_ADMIN_NAMESPACE }/onboarding/plugins/activate`,
path: `${ WC_ADMIN_NAMESPACE }/plugins/activate`,
method: 'POST',
data: { plugins: plugins.join( ',' ) },
} );

View File

@ -21,7 +21,7 @@ import {
export function* getActivePlugins() {
yield setIsRequesting( 'getActivePlugins', true );
try {
const url = WC_ADMIN_NAMESPACE + '/onboarding/plugins/active';
const url = WC_ADMIN_NAMESPACE + '/plugins/active';
const results = yield apiFetch( {
path: url,
method: 'GET',
@ -37,7 +37,7 @@ export function* getInstalledPlugins() {
yield setIsRequesting( 'getInstalledPlugins', true );
try {
const url = WC_ADMIN_NAMESPACE + '/onboarding/plugins/installed';
const url = WC_ADMIN_NAMESPACE + '/plugins/installed';
const results = yield apiFetch( {
path: url,
method: 'GET',
@ -72,7 +72,7 @@ export function* getJetpackConnectUrl( query ) {
try {
const url = addQueryArgs(
WC_ADMIN_NAMESPACE + '/onboarding/plugins/connect-jetpack',
WC_ADMIN_NAMESPACE + '/plugins/connect-jetpack',
query
);
const results = yield apiFetch( {

View File

@ -73,6 +73,7 @@ class Init {
'Automattic\WooCommerce\Admin\API\Reports\Customers\Stats\Controller',
'Automattic\WooCommerce\Admin\API\Taxes',
'Automattic\WooCommerce\Admin\API\Themes',
'Automattic\WooCommerce\Admin\API\Plugins',
);
if ( Loader::is_onboarding_enabled() ) {
@ -80,19 +81,10 @@ class Init {
$controllers,
array(
'Automattic\WooCommerce\Admin\API\OnboardingProfile',
'Automattic\WooCommerce\Admin\API\OnboardingPlugins',
'Automattic\WooCommerce\Admin\API\OnboardingTasks',
'Automattic\WooCommerce\Admin\API\OnboardingThemes',
)
);
} elseif ( Loader::is_feature_enabled( 'shipping-label-banner' ) ) {
// Shipping Banner needs to use /active /install and /activate endpoints.
$controllers = array_merge(
$controllers,
array(
\Automattic\WooCommerce\Admin\API\OnboardingPlugins::class,
)
);
}
// The performance indicators controller must be registered last, after other /stats endpoints have been registered.

View File

@ -1,6 +1,6 @@
<?php
/**
* REST API Onboarding Plugins Controller
* REST API Plugins Controller
*
* Handles requests to install and activate depedent plugins.
*
@ -16,12 +16,12 @@ use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Install_JP_And_WCS_Plugin
defined( 'ABSPATH' ) || exit;
/**
* Onboarding Plugins Controller.
* Plugins Controller.
*
* @package WooCommerce Admin/API
* @extends WC_REST_Data_Controller
*/
class OnboardingPlugins extends \WC_REST_Data_Controller {
class Plugins extends \WC_REST_Data_Controller {
/**
* Endpoint namespace.
*
@ -34,7 +34,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
*
* @var string
*/
protected $rest_base = 'onboarding/plugins';
protected $rest_base = 'plugins';
/**
* Register routes.
@ -202,7 +202,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
* @return WP_Error|array Plugin Status
*/
public function install_plugin( $request ) {
$allowed_plugins = Onboarding::get_allowed_plugins();
$allowed_plugins = self::get_allowed_plugins();
$plugin = sanitize_title_with_dashes( $request['plugin'] );
if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) {
return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 );
@ -294,16 +294,35 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
);
}
/**
* Gets an array of plugins that can be installed & activated.
*
* @return array
*/
public static function get_allowed_plugins() {
return apply_filters( 'woocommerce_admin_plugins_whitelist', array() );
}
/**
* Returns a list of active plugins in API format.
*
* @return array Active plugins
*/
public static function active_plugins() {
$allowed = self::get_allowed_plugins();
$plugins = array_values( array_intersect( PluginsHelper::get_active_plugin_slugs(), array_keys( $allowed ) ) );
return( array(
'plugins' => array_values( $plugins ),
) );
}
/**
* Returns a list of active plugins.
*
* @return array Active plugins
*/
public function active_plugins() {
$plugins = Onboarding::get_active_plugins();
return( array(
'plugins' => array_values( $plugins ),
) );
public static function get_active_plugins() {
$data = self::active_plugins();
return $data['plugins'];
}
/**
@ -324,7 +343,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
* @return WP_Error|array Plugin Status
*/
public function activate_plugins( $request ) {
$allowed_plugins = Onboarding::get_allowed_plugins();
$allowed_plugins = self::get_allowed_plugins();
$_plugins = explode( ',', $request['plugins'] );
$plugins = array_intersect( array_keys( $allowed_plugins ), $_plugins );
@ -353,7 +372,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
return( array(
'activatedPlugins' => array_values( $plugins ),
'active' => Onboarding::get_active_plugins(),
'active' => self::get_active_plugins(),
'status' => 'success',
) );
}
@ -617,7 +636,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
public function get_item_schema() {
$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'onboarding_plugin',
'title' => 'plugins',
'type' => 'object',
'properties' => array(
'slug' => array(

View File

@ -124,6 +124,7 @@ class Onboarding {
private function add_filters() {
// Rest API hooks need to run before is_admin() checks.
add_filter( 'woocommerce_rest_prepare_themes', array( $this, 'add_uploaded_theme_data' ) );
add_filter( 'woocommerce_admin_plugins_whitelist', array( $this, 'get_onboarding_allowed_plugins' ), 10, 2 );
if ( ! is_admin() ) {
return;
@ -463,8 +464,6 @@ class Onboarding {
// Only fetch if the onboarding wizard OR the task list is incomplete.
if ( self::should_show_profiler() || self::should_show_tasks() ) {
$settings['onboarding']['activePlugins'] = self::get_active_plugins();
$settings['onboarding']['installedPlugins'] = PluginsHelper::get_installed_plugin_slugs();
$settings['onboarding']['stripeSupportedCountries'] = self::get_stripe_supported_countries();
$settings['onboarding']['euCountries'] = WC()->countries->get_european_union_countries();
$settings['onboarding']['connectNonce'] = wp_create_nonce( 'connect' );
@ -574,11 +573,13 @@ class Onboarding {
/**
* Gets an array of plugins that can be installed & activated via the onboarding wizard.
*
* @param array $plugins Array of plugin slugs to be allowed.
*
* @return array
* @todo Handle edgecase of where installed plugins may have versioned folder names (i.e. `jetpack-master/jetpack.php`).
*/
public static function get_allowed_plugins() {
return apply_filters(
public static function get_onboarding_allowed_plugins( $plugins ) {
$onboarding_plugins = apply_filters(
'woocommerce_admin_onboarding_plugins_whitelist',
array(
'facebook-for-woocommerce' => 'facebook-for-woocommerce/facebook-for-woocommerce.php',
@ -596,15 +597,7 @@ class Onboarding {
'woocommerce-payments' => 'woocommerce-payments/woocommerce-payments.php',
)
);
}
/**
* Get a list of active plugins, relevent to the onboarding wizard.
*
* @return array
*/
public static function get_active_plugins() {
return array_values( array_intersect( PluginsHelper::get_active_plugin_slugs(), array_keys( self::get_allowed_plugins() ) ) );
return array_merge( $plugins, $onboarding_plugins );
}
/**

View File

@ -11,6 +11,7 @@ namespace Automattic\WooCommerce\Admin;
use \_WP_Dependency;
use Automattic\WooCommerce\Admin\Features\Onboarding;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
use Automattic\WooCommerce\Admin\API\Plugins;
/**
* Loader Class.
@ -724,7 +725,7 @@ class Loader {
$settings['dateFormat'] = get_option( 'date_format' );
$settings['plugins'] = array(
'installedPlugins' => PluginsHelper::get_installed_plugin_slugs(),
'activePlugins' => Onboarding::get_active_plugins(),
'activePlugins' => Plugins::get_active_plugins(),
);
// Plugins that depend on changing the translation work on the server but not the client -
// WooCommerce Branding is an example of this - so pass through the translation of

View File

@ -134,7 +134,7 @@ class WC_Admin_Notes_WooCommerce_Payments {
if ( self::NOTE_NAME === $note->get_name() ) {
$install_request = array( 'plugin' => self::PLUGIN_SLUG );
$installer = new \Automattic\WooCommerce\Admin\API\OnboardingPlugins();
$installer = new \Automattic\WooCommerce\Admin\API\Plugins();
$result = $installer->install_plugin( $install_request );
if ( is_wp_error( $result ) ) {

View File

@ -161,7 +161,7 @@ class WC_Tests_API_Onboarding_Profiles extends WC_REST_Unit_Test_Case {
public function test_default_params() {
$endpoints = array(
'/wc-admin/onboarding/profile',
'/wc-admin/onboarding/plugins',
'/wc-admin/plugins',
);
foreach ( $endpoints as $endpoint ) {

View File

@ -1,24 +1,23 @@
<?php
/**
* Onboarding Plugins REST API Test
* Plugins REST API Test
*
* @package WooCommerce Admin\Tests\API
*/
use \Automattic\WooCommerce\Admin\API\OnboardingPlugins;
use \Automattic\WooCommerce\Admin\Features\Onboarding;
use \Automattic\WooCommerce\Admin\API\Plugins;
/**
* WC Tests API Onboarding Plugins
* WC Tests API Plugins
*/
class WC_Tests_API_Onboarding_Plugins extends WC_REST_Unit_Test_Case {
class WC_Tests_API_Plugins extends WC_REST_Unit_Test_Case {
/**
* Endpoints.
*
* @var string
*/
protected $endpoint = '/wc-admin/onboarding/plugins';
protected $endpoint = '/wc-admin/plugins';
/**
* Setup test data. Called before every test.
@ -95,7 +94,7 @@ class WC_Tests_API_Onboarding_Plugins extends WC_REST_Unit_Test_Case {
);
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$active_plugins = Onboarding::get_active_plugins();
$active_plugins = Plugins::get_active_plugins();
$this->assertEquals( 200, $response->get_status() );
$this->assertContains( 'facebook-for-woocommerce', $data['activatedPlugins'] );