Skip to content

Instantly share code, notes, and snippets.

@damiencarbery
Last active July 15, 2024 14:34
Show Gist options
  • Save damiencarbery/625366a1fe75bf46fa22a04b5d7b47e0 to your computer and use it in GitHub Desktop.
Save damiencarbery/625366a1fe75bf46fa22a04b5d7b47e0 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Copy WooCommerce order shipping address to clipboard
Plugin URI: https://www.damiencarbery.com/2022/11/copy-woocommerce-order-shipping-address-to-clipboard/
Description: Copy the shipping (or billing) address, email, phone number, full name or order number to the clipboard for pasting in another application. A WooCommerce Community member asked how to add a button to the order admin page to copy the shipping address to the clipboard. Asked on <a href="https://www.facebook.com/groups/advanced.woocommerce/permalink/6233848903296143/">WooCommerce Community Facebook group</a>.
Author: Damien Carbery
Version: 0.6.20240715
WC tested up to: 9.1.2
Requires Plugins: woocommerce
*/
defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Utilities\OrderUtil;
class CopyOrderAddressToClipboard {
// Returns an instance of this class.
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
// Initialize the plugin variables.
public function __construct() {
$this->init();
}
// Set up WordPress specfic actions.
public function init() {
// Declare that this plugin supports WooCommerce HPOS.
add_action( 'before_woocommerce_init', function() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
} );
// Write the order address and JavaScript code to the page.
add_action( 'woocommerce_admin_order_data_after_shipping_address', array( $this, 'add_copy_data_and_icon' ) );
}
public function add_copy_data_and_icon( $order ) {
// Retrieve the shipping address.
$formattedAddress = apply_filters( 'dcwd_copy_data_shipping_address', $order->get_formatted_shipping_address(), $order );
// If shipping empty (e.g. only virtual products in the order) get billing address.
if ( empty( $formattedAddress ) ) {
$formattedAddress = apply_filters( 'dcwd_copy_data_billing_address', $order->get_formatted_billing_address(), $order );
}
$emailAddress = apply_filters( 'dcwd_copy_data_billing_email', $order->get_billing_email(), $order );
$phoneNumber = apply_filters( 'dcwd_copy_data_billing_phone', $order->get_billing_phone(), $order );
$orderNumber = $order->get_order_number();
$fullName = apply_filters( 'dcwd_copy_data_billing_full_name', $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), $order );
?>
<style>
.dcwd-copyToClipboard.copied:after { content: 'Copied'; color: green; padding-left: 0.5em; font-size: 70%; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; }
</style>
<script>
jQuery(document).ready(function( $ ) {
// Add the link markup before the Edit Address icon in the Shipping section.
$( '<a href="#" class="dcwd-copyToClipboard dcwd-copyAddress dashicons dashicons-external" title="Copy address to clipboard"></a>' ).insertBefore( '.order_data_column:nth-child(3) a.edit_address' );
$( '<a href="#" class="dcwd-copyToClipboard dcwd-copyEmail dashicons dashicons-external" title="Copy email address to clipboard"></a>' ).insertAfter( '.order_data_column:nth-child(2) .address p:nth-child(2) a' );
$( '<a href="#" class="dcwd-copyToClipboard dcwd-copyPhone dashicons dashicons-external" title="Copy phone number to clipboard"></a>' ).insertAfter( '.order_data_column:nth-child(2) .address p:nth-child(3) a' );
$('<a href="#" class="dcwd-copyToClipboard dcwd-copyFullName dashicons dashicons-external" title="Copy full name to clipboard"></a>' ).insertBefore( '.order_data_column:nth-child(2) .address br:first-child' );
// Use .append (which has opposite syntax to .insertAfter) to put the icon beside the .woocommerce-order-data__heading content.
$( '.woocommerce-order-data__heading' ).append( '<a href="#" class="dcwd-copyToClipboard dcwd-copyOrderNum dashicons dashicons-external" title="Copy order number to clipboard"></a>' );
// Add icon beside each order item name.
$( '#order_line_items tr.item' ).each( function( i ) {
item_id = $( this ).data( 'order_item_id' );
child_el = i + 1;
$( '<a href="#" class="dcwd-copyToClipboard dcwd-copyProductName dashicons dashicons-external" data-order_item_id="' + item_id + '" title="Copy product name to clipboard"></a>' ).insertAfter( $( '#order_line_items tr:nth-child('+child_el+') .wc-order-item-name') );
} );
// When the link is clicked copy the shipping name and address to the clipboard.
$( '.dcwd-copyAddress' ).click(function() {
event.preventDefault();
formattedAddress = '<?php echo $formattedAddress; ?>';
formattedAddress = formattedAddress.replace(/<br\/>/g, "\n");
navigator.clipboard.writeText(formattedAddress).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
$( '.dcwd-copyAddress' ).addClass( 'copied' );
setTimeout(() => { $( '.dcwd-copyAddress' ).removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
// When the link is clicked copy the email address to the clipboard.
$( '.dcwd-copyEmail' ).click(function() {
event.preventDefault();
emailAddress = '<?php echo $emailAddress; ?>';
navigator.clipboard.writeText(emailAddress).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
$( '.dcwd-copyEmail' ).addClass( 'copied' );
setTimeout(() => { $( '.dcwd-copyEmail' ).removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
// When the link is clicked copy the phone number to the clipboard.
$( '.dcwd-copyPhone' ).click(function() {
event.preventDefault();
phoneNumber = '<?php echo $phoneNumber; ?>';
navigator.clipboard.writeText(phoneNumber).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
$( '.dcwd-copyPhone' ).addClass( 'copied' );
setTimeout(() => { $( '.dcwd-copyPhone' ).removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
// When the link is clicked copy the order number to the clipboard.
$( '.dcwd-copyOrderNum' ).click(function() {
event.preventDefault();
orderNumber = '<?php echo $orderNumber; ?>';
navigator.clipboard.writeText(orderNumber).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
$( '.dcwd-copyOrderNum' ).addClass( 'copied' );
setTimeout(() => { $( '.dcwd-copyOrderNum' ).removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
// When the link is clicked copy the full name to the clipboard.
$( '.dcwd-copyFullName' ).click(function() {
event.preventDefault();
fullName = '<?php echo $fullName; ?>';
navigator.clipboard.writeText(fullName).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
$( '.dcwd-copyFullName' ).addClass( 'copied' );
setTimeout(() => { $( '.dcwd-copyFullName' ).removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
const product_names = [];
<?php
foreach ( $order->get_items() as $item_id => $item ) {
printf( 'product_names[%d] = "%s";%s', $item_id, $item->get_name(), "\n" );
}
?>
// When a product name is clicked then copy it to the clipboard.
$( '.dcwd-copyProductName' ).click(function() {
event.preventDefault();
item_id = $( this ).data( 'order_item_id' );
productName = product_names[ item_id ];
this_link = $( this );
navigator.clipboard.writeText(productName).then(function() {
// Add the 'copied' class and remove it 4 seconds later.
this_link.addClass( 'copied' );
setTimeout(() => { this_link.removeClass( 'copied' );; }, "4000")
}, function(err) {
// TODO: Consider some indication of the error.
console.error('Async: Could not copy text: ', err);
});
});
<?php
?>
});
</script>
<?php
}
}
$CopyOrderAddressToClipboard = new CopyOrderAddressToClipboard();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment