<?php
/**
* BulkLabelsBanner class.
*
* @package Automattic\WCShipping\Banners
*/
namespace Automattic\WCShipping\Banners;
use Automattic\WCShipping\Connect\WC_Connect_Functions;
use Automattic\WCShipping\Connect\WC_Connect_Service_Settings_Store;
use Automattic\WCShipping\LabelPurchase\OrdersShippingContextRESTController;
use Automattic\WCShipping\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Renders the bulk-labels selection banner on the order-list page.
*/
class BulkLabelsBanner {
const BULK_ACTION_CREATE_SHIPPING_LABELS = 'wcshipping_create_shipping_labels';
/**
* Service settings store used to read the saved paper-size preference.
*
* @var WC_Connect_Service_Settings_Store
*/
private $settings_store;
/**
* Constructor.
*
* @param WC_Connect_Service_Settings_Store $settings_store Used to read the merchant's saved paper-size preference.
*/
public function __construct( WC_Connect_Service_Settings_Store $settings_store ) {
$this->settings_store = $settings_store;
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_filter( 'bulk_actions-edit-shop_order', array( $this, 'register_bulk_action' ) );
add_filter( 'bulk_actions-woocommerce_page_wc-orders', array( $this, 'register_bulk_action' ) );
}
/**
* Enqueue the bulk labels banner script on order list pages.
*/
public function enqueue_scripts() {
if ( ! $this->should_render() ) {
return;
}
/**
* Fires when a WCShipping entry-point script should be enqueued.
*
* @since 2.4.0
*/
do_action(
'wcshipping_enqueue_script',
'woocommerce-shipping-bulk-labels-banner',
array(
// Surface the batch cap so the JS gates can match the
// downstream batch endpoints without re-declaring
// BATCH_SIZE_CAP on the client.
'bulk_labels_max_orders' => OrdersShippingContextRESTController::BATCH_SIZE_CAP,
// Full purchase settings, hydrated on the orders list page so
// consumers of WCShipping_Config can read the saved paper-size
// preference without a round-trip, and so any client-side
// updater (e.g. `persistPaperSize`) can POST the complete
// current row back to the account-settings endpoint. The
// endpoint's `update_account_settings()` defaults any missing
// boolean to `false`, so a paper-size-only POST would silently
// flip `enabled`, `email_receipts`, etc. and disable the
// label-purchase metabox account-wide.
'accountSettings' => array(
'purchaseSettings' => $this->settings_store->get_account_settings(),
),
)
);
}
/**
* Add the bulk labels action to the order list bulk actions menu.
*
* @param array $actions Bulk actions keyed by action ID.
* @return array
*/
public function register_bulk_action( array $actions ): array {
if ( ! $this->should_render() ) {
return $actions;
}
$action = array(
self::BULK_ACTION_CREATE_SHIPPING_LABELS => __( 'Fulfill with labels', 'woocommerce-shipping' ),
);
if ( isset( $actions['trash'] ) ) {
return $this->insert_action_after( $actions, 'trash', $action );
}
return array_merge( $actions, $action );
}
/**
* Whether the banner should render on the current screen.
*
* @return bool
*/
private function should_render(): bool {
if ( ! Utils::is_orders_screen() ) {
return false;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check of a GET param.
$action = isset( $_GET['action'] ) ? wc_clean( wp_unslash( $_GET['action'] ) ) : '';
if ( 'edit' === $action ) {
return false;
}
return WC_Connect_Functions::user_can_manage_labels() !== false;
}
/**
* Insert a bulk action after an existing action.
*
* @param array $actions Bulk actions keyed by action ID.
* @param string $after_action Action ID to insert after.
* @param array $new_action Action to insert.
* @return array
*/
private function insert_action_after( array $actions, string $after_action, array $new_action ): array {
$updated_actions = array();
foreach ( $actions as $action_id => $label ) {
$updated_actions[ $action_id ] = $label;
if ( $after_action === $action_id ) {
$updated_actions = array_merge( $updated_actions, $new_action );
}
}
return $updated_actions;
}
}