/*
* Snippet Name: Create and Manage Custom WooCommerce Order Statuses.
* Snippet Author: diviengine.com
*/
// Add menu item under WooCommerce
add_action('admin_menu', 'add_custom_order_status_menu');
function add_custom_order_status_menu() {
add_submenu_page(
'woocommerce',
'Custom Order Status',
'Custom Order Status',
'manage_woocommerce',
'custom-order-status',
'custom_order_status_page'
);
}
// Custom Order Status page content
function custom_order_status_page() {
?>
<div class="wrap">
<h1>Custom Order Status Manager</h1>
<!-- Info Box Start -->
<div class="de-info-box" style="border: 1px solid #ccd0d4; background-color: #f1f1f1; padding: 15px; margin-bottom: 20px; display: flex; align-items: center;">
<img src="https://diviengine.com/wp-content/uploads/2023/12/logo.png" alt="Divi Engine Logo" style="max-width: 150px; height: auto; margin-right: 20px;">
<p style="margin: 0; font-size: 14px; color: #23282d;">
<?php esc_html_e( 'Get 10% off any plugin or All-Access Pass with the coupon code ', 'mytheme' ); ?>
<strong>snippetengine</strong>
<?php esc_html_e( ' at ', 'mytheme' ); ?>
<a href="https://diviengine.com" target="_blank" style="color: #0073aa; text-decoration: none;"><?php esc_html_e( 'diviengine.com', 'mytheme' ); ?></a>.
</p>
</div>
<!-- Info Box End -->
<?php
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['add_status'])) {
add_custom_order_status(sanitize_text_field($_POST['status_name']), sanitize_text_field($_POST['status_label']));
} elseif (isset($_POST['edit_status'])) {
edit_custom_order_status(sanitize_text_field($_POST['status_id']), sanitize_text_field($_POST['status_name']), sanitize_text_field($_POST['status_label']));
} elseif (isset($_POST['delete_status'])) {
delete_custom_order_status(sanitize_text_field($_POST['status_id']));
}
}
// Display existing custom statuses
$custom_statuses = get_option('custom_order_statuses', array());
?>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Label</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($custom_statuses as $id => $status): ?>
<tr>
<td><?php echo esc_html($id); ?></td>
<td>
<span class="status-name-display" style="display: <?php echo isset($_POST['edit_status']) && $_POST['status_id'] == $id ? 'none' : 'inline'; ?>;">
<?php echo esc_html($status['name']); ?>
</span>
<form method="post" style="display: <?php echo isset($_POST['edit_status']) && $_POST['status_id'] == $id ? 'inline' : 'none'; ?>;">
<input type="text" name="status_name" value="<?php echo esc_attr($status['name']); ?>" required>
<input type="hidden" name="status_id" value="<?php echo esc_attr($id); ?>">
</td>
<td>
<span class="status-label-display" style="display: <?php echo isset($_POST['edit_status']) && $_POST['status_id'] == $id ? 'none' : 'inline'; ?>;">
<?php echo esc_html($status['label']); ?>
</span>
<input type="text" name="status_label" value="<?php echo esc_attr($status['label']); ?>" style="display: <?php echo isset($_POST['edit_status']) && $_POST['status_id'] == $id ? 'inline' : 'none'; ?>;" required>
</td>
<td>
<?php if (isset($_POST['edit_status']) && $_POST['status_id'] == $id): ?>
<input type="submit" name="edit_status" value="Save" class="button button-small">
<a href="<?php echo esc_url(admin_url('admin.php?page=custom-order-status')); ?>" class="button button-small">Cancel</a>
</form>
<?php else: ?>
<form method="post" style="display: inline;">
<input type="hidden" name="status_id" value="<?php echo esc_attr($id); ?>">
<input type="submit" name="edit_status" value="Edit" class="button button-small">
<input type="submit" name="delete_status" value="Delete" class="button button-small" onclick="return confirm('Are you sure you want to delete this status?');">
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h2><?php esc_html_e('Add New Custom Status', 'mytheme'); ?></h2>
<form method="post">
<input type="text" name="status_name" placeholder="<?php esc_attr_e('Status Name', 'mytheme'); ?>" required>
<input type="text" name="status_label" placeholder="<?php esc_attr_e('Status Label', 'mytheme'); ?>" required>
<input type="submit" name="add_status" value="<?php esc_attr_e('Add Status', 'mytheme'); ?>" class="button button-primary">
</form>
</div>
<?php
}
// Add custom order status
function add_custom_order_status($name, $label) {
$custom_statuses = get_option('custom_order_statuses', array());
$id = 'wc-' . sanitize_title($name);
if (!isset($custom_statuses[$id])) {
$custom_statuses[$id] = array(
'name' => $name,
'label' => $label
);
update_option('custom_order_statuses', $custom_statuses);
} else {
// Handle duplicate status error
add_action('admin_notices', function() use ($name) {
echo '<div class="notice notice-error"><p>' . sprintf(esc_html__('Order status "%s" already exists.', 'mytheme'), esc_html($name)) . '</p></div>';
});
}
}
// Edit custom order status
function edit_custom_order_status($id, $name, $label) {
$custom_statuses = get_option('custom_order_statuses', array());
if (isset($custom_statuses[$id])) {
$custom_statuses[$id]['name'] = $name;
$custom_statuses[$id]['label'] = $label;
update_option('custom_order_statuses', $custom_statuses);
}
}
// Delete custom order status
function delete_custom_order_status($id) {
$custom_statuses = get_option('custom_order_statuses', array());
if (isset($custom_statuses[$id])) {
unset($custom_statuses[$id]);
update_option('custom_order_statuses', $custom_statuses);
}
}
// Register custom order statuses
add_filter('woocommerce_register_shop_order_post_statuses', 'register_custom_order_statuses');
function register_custom_order_statuses($order_statuses) {
$custom_statuses = get_option('custom_order_statuses', array());
foreach ($custom_statuses as $id => $status) {
$order_statuses[$id] = array(
'label' => $status['label'],
'public' => false,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop($status['label'] . ' <span class="count">(%s)</span>', $status['label'] . ' <span class="count">(%s)</span>', 'woocommerce'),
);
}
return $order_statuses;
}
// Add custom order statuses to order status list
add_filter('wc_order_statuses', 'add_custom_order_statuses_to_list');
function add_custom_order_statuses_to_list($order_statuses) {
$custom_statuses = get_option('custom_order_statuses', array());
foreach ($custom_statuses as $id => $status) {
$order_statuses[$id] = $status['label'];
}
return $order_statuses;
}
// Add custom order statuses to bulk actions
add_filter('bulk_actions-edit-shop_order', 'add_custom_order_statuses_to_bulk_actions');
function add_custom_order_statuses_to_bulk_actions($bulk_actions) {
$custom_statuses = get_option('custom_order_statuses', array());
foreach ($custom_statuses as $id => $status) {
$bulk_actions['mark_' . substr($id, 3)] = 'Change status to ' . $status['label'];
}
return $bulk_actions;
}
// Add custom statuses to order list actions dropdown
add_action('woocommerce_admin_order_actions_end', 'add_custom_order_statuses_to_order_actions', 20, 1);
function add_custom_order_statuses_to_order_actions($order) {
$custom_statuses = get_option('custom_order_statuses', array());
foreach ($custom_statuses as $id => $status) {
if ($order->get_status() !== substr($id, 3)) {
echo '<a class="button tips custom-order-status-button" href="' . wp_nonce_url(admin_url('post.php?post=' . $order->get_id() . '&action=edit&mark_order_status=' . $id), 'woocommerce-mark-order-status') . '" aria-label="' . esc_attr__('Change order status to ', 'woocommerce') . esc_html($status['label']) . '" data-tip="' . esc_attr($status['label']) . '">' . esc_html($status['label']) . '</a>';
}
}
}