get( \Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled()
? wc_get_page_screen_id( 'shop-order' )
: 'shop_order';
add_meta_box(
'ordercourier_order_actions',
__( 'OrderCourier Actions', 'ordercourier' ),
array( $this, 'render_order_metabox' ),
$screen,
'side',
'default'
);
}
/**
* Render order metabox.
*
* @param \WP_Post|\WC_Order $post_or_order Post or order object.
*/
public function render_order_metabox( $post_or_order ) {
$order = $post_or_order instanceof \WC_Order ? $post_or_order : wc_get_order( $post_or_order->ID );
if ( ! $order ) {
return;
}
$channel = $order->get_meta( '_oc_channel' );
if ( 'chat' !== $channel ) {
echo '
' . esc_html__( 'This is not a chat order.', 'ordercourier' ) . '
';
return;
}
$agent_id = $order->get_meta( '_oc_agent_id' );
$agent_phone = $order->get_meta( '_oc_agent_phone' );
$sent_at = $order->get_meta( '_oc_sent_at' );
// Display agent name or phone.
if ( $agent_id ) {
$agent_name = get_the_title( $agent_id );
} elseif ( $agent_phone ) {
$agent_name = $agent_phone;
} else {
$agent_name = __( 'Default', 'ordercourier' );
}
?>
$template ) {
$url = \Prologic365\OrderCourier\Order_Manager::get_order_message_url( $order->get_id(), 'order' );
?>
is_plugin_screen( $hook ) ) {
wp_enqueue_style( 'ordercourier-admin', ORDERCOURIER_URL . 'assets/css/admin.css', array(), ORDERCOURIER_VERSION );
wp_enqueue_script( 'ordercourier-admin', ORDERCOURIER_URL . 'assets/js/admin.js', array( 'jquery' ), ORDERCOURIER_VERSION, true );
/**
* Action for PRO and other add-ons to enqueue their admin assets.
*
* @since 1.0.0
* @param string $hook Current admin page hook.
*/
do_action( 'ordercourier_admin_enqueue_scripts', $hook );
}
}
/**
* Whether the current admin screen is one where this plugin shows UI.
*
* That is the OrderCourier tab in WooCommerce settings and the order edit screen
* (both the classic post screen and the HPOS orders screen).
*
* @param string $hook Admin page hook.
* @return bool
*/
public function is_plugin_screen( $hook ) {
if ( 'woocommerce_page_wc-settings' === $hook ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only reads which settings tab is open.
$tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
return 'ordercourier' === $tab;
}
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
if ( ! $screen ) {
return false;
}
$order_screens = array( 'shop_order' );
if ( function_exists( 'wc_get_page_screen_id' ) ) {
$order_screens[] = wc_get_page_screen_id( 'shop-order' );
}
return in_array( $screen->id, $order_screens, true );
}
/**
* Add category phone field (add form).
*
* @param string $taxonomy Taxonomy slug.
*/
public function add_category_phone_field_new( $taxonomy ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
wp_nonce_field( 'ordercourier_save_term', 'ordercourier_term_nonce' );
?>
term_id, '_oc_agent_phone', true );
?>
|
|
|
validate( $phone ) ) {
// Invalid phone, don't save and show error via transient.
set_transient( 'ordercourier_phone_validation_error_' . get_current_user_id(), 'category', 10 );
return;
}
// Normalize to digits only (E.164 without +).
$normalized_phone = $validator->normalize( $phone );
$normalized_phone = ltrim( $normalized_phone, '+' );
update_term_meta( $term_id, '_oc_agent_phone', $normalized_phone );
} else {
delete_term_meta( $term_id, '_oc_agent_phone' );
}
}
}
/**
* Add product phone field.
*/
public function add_product_phone_field() {
global $post;
echo '';
wp_nonce_field( 'ordercourier_save_product', 'ordercourier_product_nonce' );
woocommerce_wp_text_input(
array(
'id' => '_oc_agent_phone',
'label' => __( 'OrderCourier Phone', 'ordercourier' ),
'placeholder' => '+1234567890',
'desc_tip' => true,
'description' => __( 'Override the default phone number for this product (E.164 format).', 'ordercourier' ),
'value' => get_post_meta( $post->ID, '_oc_agent_phone', true ),
)
);
woocommerce_wp_checkbox(
array(
'id' => '_oc_quote_only',
'label' => __( 'Quote Only', 'ordercourier' ),
'description' => __( 'The chat button asks for a price instead of sending an order. The product price is still visible to customers.', 'ordercourier' ),
'value' => get_post_meta( $post->ID, '_oc_quote_only', true ),
)
);
woocommerce_wp_checkbox(
array(
'id' => '_oc_disable',
'label' => __( 'Hide Chat Button', 'ordercourier' ),
'description' => __( 'Hide the chat button for this product.', 'ordercourier' ),
'value' => get_post_meta( $post->ID, '_oc_disable', true ),
)
);
echo '
';
}
/**
* Save product phone field.
*
* @param int $post_id Product ID.
*/
public function save_product_phone_field( $post_id ) {
if ( ! isset( $_POST['ordercourier_product_nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['ordercourier_product_nonce'] ) ), 'ordercourier_save_product' ) ) {
return;
}
// Verify user capabilities.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
// Save quote only checkbox.
if ( isset( $_POST['_oc_quote_only'] ) ) {
update_post_meta( $post_id, '_oc_quote_only', 'yes' );
} else {
delete_post_meta( $post_id, '_oc_quote_only' );
}
// Save disable button checkbox.
if ( isset( $_POST['_oc_disable'] ) ) {
update_post_meta( $post_id, '_oc_disable', 'yes' );
} else {
delete_post_meta( $post_id, '_oc_disable' );
}
if ( isset( $_POST['_oc_agent_phone'] ) ) {
$phone = sanitize_text_field( wp_unslash( $_POST['_oc_agent_phone'] ) );
if ( ! empty( $phone ) ) {
// Validate and normalize phone number.
$validator = new \Prologic365\OrderCourier\Phone_Validator();
if ( ! $validator->validate( $phone ) ) {
// Invalid phone, don't save and show error via transient.
set_transient( 'ordercourier_phone_validation_error_' . get_current_user_id(), 'product', 10 );
return;
}
// Normalize to digits only (E.164 without +).
$normalized_phone = $validator->normalize( $phone );
$normalized_phone = ltrim( $normalized_phone, '+' );
update_post_meta( $post_id, '_oc_agent_phone', $normalized_phone );
} else {
delete_post_meta( $post_id, '_oc_agent_phone' );
}
}
}
/**
* Display phone validation error notice.
*/
public function display_phone_validation_error() {
// Only on the product and product category screens, where the phone field is saved.
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
if ( ! $screen || 'product' !== $screen->post_type || ! in_array( $screen->base, array( 'post', 'edit-tags', 'term' ), true ) ) {
return;
}
$user_id = get_current_user_id();
$error_type = get_transient( 'ordercourier_phone_validation_error_' . $user_id );
if ( $error_type ) {
delete_transient( 'ordercourier_phone_validation_error_' . $user_id );
$message = sprintf(
/* translators: %s: error context (product or category) */
__( 'OrderCourier: Invalid phone number format for %s. Please use E.164 format (e.g., +1234567890). The number was not saved.', 'ordercourier' ),
$error_type
);
echo '' . esc_html( $message ) . '
';
}
}
}