Merge pull request #29174 from woocommerce/add/28568-dashboard-widget-finish-setup
Add/28568 dashboard widget - setup
This commit is contained in:
commit
00a272fa85
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* dashboard-setup.scss
|
||||||
|
* Styles for WooCommerce dashboard finish setup widgets
|
||||||
|
* only loaded on the dashboard itself.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Styling begins
|
||||||
|
*/
|
||||||
|
|
||||||
|
.dashboard-widget-finish-setup {
|
||||||
|
|
||||||
|
.progress-wrapper {
|
||||||
|
border: 1px solid #757575;
|
||||||
|
border-radius: 16px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
padding: 2px 8px 2px 8px;
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-wrapper span {
|
||||||
|
position: relative;
|
||||||
|
top: -3px;
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description div {
|
||||||
|
margin-top: 11px;
|
||||||
|
float: left;
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description img {
|
||||||
|
float: right;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-progress {
|
||||||
|
margin-top: 1px;
|
||||||
|
margin-left: -3px;
|
||||||
|
|
||||||
|
circle {
|
||||||
|
stroke: #f0f0f0;
|
||||||
|
stroke-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
stroke: #949494;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,211 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Admin Dashboard - Setup
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Admin
|
||||||
|
* @version 2.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Automattic\Jetpack\Constants;
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit; // Exit if accessed directly.
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WC_Admin_Dashboard_Setup', false ) ) :
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WC_Admin_Dashboard_Setup Class.
|
||||||
|
*/
|
||||||
|
class WC_Admin_Dashboard_Setup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of tasks.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $tasks = array(
|
||||||
|
'store_details' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&path=%2Fsetup-wizard',
|
||||||
|
),
|
||||||
|
'products' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&task=products',
|
||||||
|
),
|
||||||
|
'woocommerce-payments' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&path=%2Fpayments%2Fconnect',
|
||||||
|
),
|
||||||
|
'payments' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&task=payments',
|
||||||
|
),
|
||||||
|
'tax' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&task=tax',
|
||||||
|
),
|
||||||
|
'shipping' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&task=shipping',
|
||||||
|
),
|
||||||
|
'appearance' => array(
|
||||||
|
'completed' => false,
|
||||||
|
'button_link' => 'admin.php?page=wc-admin&task=appearance',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # of completed tasks.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $completed_tasks_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WC_Admin_Dashboard_Setup constructor.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
if ( $this->should_display_widget() ) {
|
||||||
|
$this->populate_general_tasks();
|
||||||
|
$this->populate_payment_tasks();
|
||||||
|
$this->completed_tasks_count = $this->get_completed_tasks_count();
|
||||||
|
add_meta_box(
|
||||||
|
'wc_admin_dashboard_setup',
|
||||||
|
__( 'WooCommerce Setup', 'woocommerce' ),
|
||||||
|
array( $this, 'render' ),
|
||||||
|
'dashboard',
|
||||||
|
'normal',
|
||||||
|
'high'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render meta box output.
|
||||||
|
*/
|
||||||
|
public function render() {
|
||||||
|
$version = Constants::get_constant( 'WC_VERSION' );
|
||||||
|
wp_enqueue_style( 'wc-dashboard-setup', WC()->plugin_url() . '/assets/css/dashboard-setup.css', array(), $version );
|
||||||
|
|
||||||
|
$task = $this->get_next_task();
|
||||||
|
if ( ! $task ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$button_link = $task['button_link'];
|
||||||
|
$completed_tasks_count = $this->completed_tasks_count;
|
||||||
|
$tasks_count = count( $this->tasks );
|
||||||
|
|
||||||
|
// Given 'r' (circle element's r attr), dashoffset = ((100-$desired_percentage)/100) * PI * (r*2).
|
||||||
|
$progress_percentage = ( $completed_tasks_count / $tasks_count ) * 100;
|
||||||
|
$circle_r = 6.5;
|
||||||
|
$circle_dashoffset = ( ( 100 - $progress_percentage ) / 100 ) * ( pi() * ( $circle_r * 2 ) );
|
||||||
|
|
||||||
|
include __DIR__ . '/views/html-admin-dashboard-setup.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate tasks from the database.
|
||||||
|
*/
|
||||||
|
private function populate_general_tasks() {
|
||||||
|
$tasks = get_option( 'woocommerce_task_list_tracked_completed_tasks', array() );
|
||||||
|
foreach ( $tasks as $task ) {
|
||||||
|
if ( isset( $this->tasks[ $task ] ) ) {
|
||||||
|
$this->tasks[ $task ]['completed'] = true;
|
||||||
|
$this->tasks[ $task ]['button_link'] = wc_admin_url( $this->tasks[ $task ]['button_link'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for $tasks
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_tasks() {
|
||||||
|
return $this->tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return # of completed tasks
|
||||||
|
*/
|
||||||
|
public function get_completed_tasks_count() {
|
||||||
|
$completed_tasks = array_filter(
|
||||||
|
$this->tasks,
|
||||||
|
function( $task ) {
|
||||||
|
return $task['completed'];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return count( $completed_tasks );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next task.
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
private function get_next_task() {
|
||||||
|
foreach ( $this->get_tasks() as $task ) {
|
||||||
|
if ( false === $task['completed'] ) {
|
||||||
|
return $task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if we should display the widget
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function should_display_widget() {
|
||||||
|
return 'yes' !== get_option( 'woocommerce_task_list_complete' ) && 'yes' !== get_option( 'woocommerce_task_list_hidden' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate payment tasks's visibility and completion
|
||||||
|
*/
|
||||||
|
private function populate_payment_tasks() {
|
||||||
|
$is_woo_payment_installed = is_plugin_active( 'woocommerce-payments/woocommerce-payments.php' );
|
||||||
|
$country = explode( ':', get_option( 'woocommerce_default_country', '' ) )[0];
|
||||||
|
|
||||||
|
// woocommerce-payments requires its plugin activated and country must be US.
|
||||||
|
if ( ! $is_woo_payment_installed || 'US' !== $country ) {
|
||||||
|
unset( $this->tasks['woocommerce-payments'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// payments can't be used when woocommerce-payments exists and country is US.
|
||||||
|
if ( $is_woo_payment_installed || 'US' === $country ) {
|
||||||
|
unset( $this->tasks['payments'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $this->tasks['payments'] ) ) {
|
||||||
|
$gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||||
|
$enabled_gateways = array_filter(
|
||||||
|
$gateways,
|
||||||
|
function ( $gateway ) {
|
||||||
|
return 'yes' === $gateway->enabled;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$this->tasks['payments']['completed'] = ! empty( $enabled_gateways );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $this->tasks['woocommerce-payments'] ) ) {
|
||||||
|
$wc_pay_is_connected = false;
|
||||||
|
if ( class_exists( '\WC_Payments' ) ) {
|
||||||
|
$wc_payments_gateway = \WC_Payments::get_gateway();
|
||||||
|
$wc_pay_is_connected = method_exists( $wc_payments_gateway, 'is_connected' )
|
||||||
|
? $wc_payments_gateway->is_connected()
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
$this->tasks['woocommerce-payments']['completed'] = $wc_pay_is_connected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endif;
|
||||||
|
|
||||||
|
return new WC_Admin_Dashboard_Setup();
|
|
@ -24,7 +24,7 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
// Only hook in admin parts if the user has admin access.
|
// Only hook in admin parts if the user has admin access.
|
||||||
if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
|
if ( $this->should_display_widget() ) {
|
||||||
// If on network admin, only load the widget that works in that context and skip the rest.
|
// If on network admin, only load the widget that works in that context and skip the rest.
|
||||||
if ( is_multisite() && is_network_admin() ) {
|
if ( is_multisite() && is_network_admin() ) {
|
||||||
add_action( 'wp_network_dashboard_setup', array( $this, 'register_network_order_widget' ) );
|
add_action( 'wp_network_dashboard_setup', array( $this, 'register_network_order_widget' ) );
|
||||||
|
@ -57,6 +57,17 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
|
||||||
wp_add_dashboard_widget( 'woocommerce_network_orders', __( 'WooCommerce Network Orders', 'woocommerce' ), array( $this, 'network_orders' ) );
|
wp_add_dashboard_widget( 'woocommerce_network_orders', __( 'WooCommerce Network Orders', 'woocommerce' ), array( $this, 'network_orders' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if we should display the widget.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function should_display_widget() {
|
||||||
|
$has_permission = current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' );
|
||||||
|
$task_completed_or_hidden = 'yes' === get_option( 'woocommerce_task_list_complete' ) || 'yes' === get_option( 'woocommerce_task_list_hidden' );
|
||||||
|
return $task_completed_or_hidden && $has_permission;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get top seller from DB.
|
* Get top seller from DB.
|
||||||
*
|
*
|
||||||
|
|
|
@ -94,6 +94,7 @@ class WC_Admin {
|
||||||
switch ( $screen->id ) {
|
switch ( $screen->id ) {
|
||||||
case 'dashboard':
|
case 'dashboard':
|
||||||
case 'dashboard-network':
|
case 'dashboard-network':
|
||||||
|
include __DIR__ . '/class-wc-admin-dashboard-setup.php';
|
||||||
include __DIR__ . '/class-wc-admin-dashboard.php';
|
include __DIR__ . '/class-wc-admin-dashboard.php';
|
||||||
break;
|
break;
|
||||||
case 'options-permalink':
|
case 'options-permalink':
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Admin View: Dashboard - Finish Setup
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="dashboard-widget-finish-setup">
|
||||||
|
<span class='progress-wrapper'>
|
||||||
|
<svg class="circle-progress" width="17" height="17" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle r="6.5" cx="10" cy="10" fill="transparent" stroke-dasharray="40.859" stroke-dashoffset="0"></circle>
|
||||||
|
<circle class="bar" r="6.5" cx="190" cy="10" fill="transparent" stroke-dasharray="40.859" stroke-dashoffset="<?php echo esc_attr( $circle_dashoffset ); ?>" transform='rotate(-90 100 100)'></circle>
|
||||||
|
</svg>
|
||||||
|
<span><?php echo esc_html_e( 'Step', 'woocommerce' ); ?> <?php echo esc_html( $completed_tasks_count ); ?> <?php echo esc_html_e( 'of', 'woocommerce' ); ?> <?php echo esc_html( $tasks_count ); ?></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="description">
|
||||||
|
<div>
|
||||||
|
<?php echo esc_html_e( 'You\'re almost there! Once you complete store setup you can start receiving orders.', 'woocommerce' ); ?>
|
||||||
|
<div><a href='<?php echo esc_attr( $button_link ); ?>' class='button button-primary'><?php echo esc_html_e( 'Start selling', 'woocommerce' ); ?></a></div>
|
||||||
|
</div>
|
||||||
|
<img src="<?php echo esc_url( WC()->plugin_url() ); ?>/assets/images/dashboard-widget-setup.png" />
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Tests for the WC_Admin_Dashboard_Setup class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Tests\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class WC_Admin_Dashboard_Setup_Test
|
||||||
|
*/
|
||||||
|
class WC_Admin_Dashboard_Setup_Test extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up
|
||||||
|
*/
|
||||||
|
public function setUp() {
|
||||||
|
// set default country to US so that 'payments' task does not get added.
|
||||||
|
// we want to remove payment tasks as they depend on installation & activation.
|
||||||
|
update_option( 'woocommerce_default_country', 'US' );
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes widget class and return the class.
|
||||||
|
*
|
||||||
|
* @return WC_Admin_Dashboard_Setup
|
||||||
|
*/
|
||||||
|
public function get_widget() {
|
||||||
|
return include __DIR__ . '/../../../../includes/admin/class-wc-admin-dashboard-setup.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return widget output (HTML).
|
||||||
|
*
|
||||||
|
* @return string Render widget HTML
|
||||||
|
*/
|
||||||
|
public function get_widget_output() {
|
||||||
|
update_option( 'woocommerce_task_list_hidden', 'no' );
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->get_widget()->render();
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests widget does not get rendered when woocommerce_task_list_hidden or woocommerce_task_list_hidden
|
||||||
|
* is true.
|
||||||
|
*
|
||||||
|
* @dataProvider should_display_widget_data_provider
|
||||||
|
*
|
||||||
|
* @param array $options a set of options.
|
||||||
|
*/
|
||||||
|
public function test_widget_does_not_get_rendered( array $options ) {
|
||||||
|
global $wp_meta_boxes;
|
||||||
|
|
||||||
|
foreach ( $options as $name => $value ) {
|
||||||
|
update_option( $name, $value );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->get_widget();
|
||||||
|
$this->assertNull( $wp_meta_boxes );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given both woocommerce_task_list_hidden and woocommerce_task_list_complete are false
|
||||||
|
* Then the widget should be added to the $wp_meta_boxes
|
||||||
|
*/
|
||||||
|
public function test_widget_gets_rendered_when_both_options_are_false() {
|
||||||
|
global $wp_meta_boxes;
|
||||||
|
update_option( 'woocommerce_task_list_complete', false );
|
||||||
|
update_option( 'woocommerce_task_list_hidden', false );
|
||||||
|
|
||||||
|
$this->get_widget();
|
||||||
|
$this->assertArrayHasKey( 'wc_admin_dashboard_setup', $wp_meta_boxes['dashboard']['normal']['high'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the widget output when 0 task has been completed.
|
||||||
|
*/
|
||||||
|
public function test_initial_widget_output() {
|
||||||
|
$html = $this->get_widget_output();
|
||||||
|
|
||||||
|
$required_strings = array(
|
||||||
|
'Step 0 of 5',
|
||||||
|
'You're almost there! Once you complete store setup you can start receiving orders.',
|
||||||
|
'Start selling',
|
||||||
|
'admin.php\?page=wc-admin&path=%2Fsetup-wizard',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $required_strings as $required_string ) {
|
||||||
|
$this->assertRegexp( "/${required_string}/", $html );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests completed task count as it completes one by one
|
||||||
|
*/
|
||||||
|
public function test_widget_renders_completed_task_count() {
|
||||||
|
$completed_tasks = array();
|
||||||
|
$tasks = $this->get_widget()->get_tasks();
|
||||||
|
$tasks_count = count( $tasks );
|
||||||
|
foreach ( $tasks as $key => $task ) {
|
||||||
|
array_push( $completed_tasks, $key );
|
||||||
|
update_option( 'woocommerce_task_list_tracked_completed_tasks', $completed_tasks );
|
||||||
|
$completed_tasks_count = count( $completed_tasks );
|
||||||
|
// When all tasks are completed, assert that the widget output is empty.
|
||||||
|
// As widget won't be rendered when tasks are completed.
|
||||||
|
if ( $completed_tasks_count === $tasks_count ) {
|
||||||
|
$this->assertEmpty( $this->get_widget_output() );
|
||||||
|
} else {
|
||||||
|
$this->assertRegexp( "/Step ${completed_tasks_count} of 5/", $this->get_widget_output() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides dataset that controls output of `should_display_widget`
|
||||||
|
*/
|
||||||
|
public function should_display_widget_data_provider() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'woocommerce_task_list_complete' => 'yes',
|
||||||
|
'woocommerce_task_list_hidden' => 'no',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'woocommerce_task_list_complete' => 'no',
|
||||||
|
'woocommerce_task_list_hidden' => 'yes',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue