Skip to content

Instantly share code, notes, and snippets.

@barryhughes
Created June 30, 2025 18:56
Show Gist options
  • Save barryhughes/aba4abf8a63d463301092efe50ecc519 to your computer and use it in GitHub Desktop.
Save barryhughes/aba4abf8a63d463301092efe50ecc519 to your computer and use it in GitHub Desktop.
Consolidate the subscriptions admin list into the orders admin list (prototype/early POC)
<?php
/**
* Plugin Name: Simple Subscriptions UI
* Description: Simplifies the WooCommerce Subscriptions admin UI. Prototype/experimental.
* Version: 1.0.0
* Text Domain: simple-subscriptions-ui
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*
* @package simple-subscriptions-ui
*/
// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Main plugin class.
*/
class Simple_Subscriptions_UI {
/**
* The single instance of the class.
*
* @var Simple_Subscriptions_UI
*/
protected static $_instance = null;
/**
* Main Simple_Subscriptions_UI instance.
*
* @static
* @return Simple_Subscriptions_UI
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Constructor.
*/
public function __construct() {
// Define plugin constants
$this->define_constants();
// Initialize hooks
$this->init_hooks();
}
/**
* Define plugin constants.
*/
private function define_constants() {
define( 'SIMPLE_SUBSCRIPTIONS_UI_VERSION', '1.0.0' );
define( 'SIMPLE_SUBSCRIPTIONS_UI_FILE', __FILE__ );
define( 'SIMPLE_SUBSCRIPTIONS_UI_PATH', plugin_dir_path( __FILE__ ) );
define( 'SIMPLE_SUBSCRIPTIONS_UI_URL', plugin_dir_url( __FILE__ ) );
}
/**
* Initialize hooks.
*/
private function init_hooks() {
// Add filter to add subscriptions tab to WooCommerce Orders screen
add_filter( 'views_woocommerce_page_wc-orders', array( $this, 'add_subscriptions_tab_to_orders_screen' ), 10, 1 );
// Add filter to modify the query to include subscriptions when the subscriptions tab is selected
add_filter( 'woocommerce_order_list_table_prepare_items_query_args', array( $this, 'filter_orders_to_include_subscriptions' ), 10, 1 );
// Add filter to modify the columns in the orders table when in the Subscriptions view
add_filter( 'woocommerce_shop_order_list_table_columns', array( $this, 'modify_columns_for_subscriptions_view' ), 20, 1 );
// Add action to modify the column content in the orders table when in the Subscriptions view
add_action( 'woocommerce_shop_order_list_table_custom_column', array( $this, 'display_subscription_details_column' ), 20, 2 );
// Remove the default subscription relationship column content when in the Subscriptions view
add_action( 'admin_init', array( $this, 'maybe_remove_default_subscription_column_content' ) );
// Add CSS to hide the default subscription relationship column content when in the Subscriptions view
add_action( 'admin_head', array( $this, 'add_subscription_details_css' ) );
// Add CSS to hide the Subscriptions menu item as a fallback
add_action( 'admin_head', array( $this, 'hide_subscription_menu_css' ) );
// Remove the WooCommerce Subscriptions admin screen
add_action( 'init', array( $this, 'remove_subscriptions_admin_screen' ), 10 );
}
/**
* Filter orders to include subscriptions when the subscriptions tab is selected.
*
* @param array $query_args Query arguments for the orders list table.
* @return array Modified query arguments.
*/
public function filter_orders_to_include_subscriptions( $query_args ) {
// Check if we're on the subscriptions tab
if ( isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'] ) {
// Modify the query to fetch subscription orders
$query_args['type'] = 'shop_subscription';
// Include all subscription statuses
if ( function_exists( 'wcs_get_subscription_statuses' ) ) {
$subscription_statuses = array_keys( wcs_get_subscription_statuses() );
// If status is already set, merge with subscription statuses
if ( isset( $query_args['status'] ) && ! empty( $query_args['status'] ) ) {
if ( is_array( $query_args['status'] ) ) {
$query_args['status'] = array_merge( $query_args['status'], $subscription_statuses );
} else {
$query_args['status'] = array_merge( array( $query_args['status'] ), $subscription_statuses );
}
} else {
$query_args['status'] = $subscription_statuses;
}
}
}
return $query_args;
}
/**
* Modify columns for the Subscriptions view.
*
* @param array $columns Array of columns.
* @return array Modified array of columns.
*/
public function modify_columns_for_subscriptions_view( $columns ) {
// Check if we're on the subscriptions tab
if ( isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'] ) {
// If the subscription_relationship column exists, modify its header
if ( isset( $columns['subscription_relationship'] ) ) {
$columns['subscription_relationship'] = __( 'Subscription Details', 'simple-subscriptions-ui' );
}
}
return $columns;
}
/**
* Display subscription details in the column.
*
* @param string $column_name The column name.
* @param WC_Order $order The order object.
*/
public function display_subscription_details_column( $column_name, $order ) {
// Only process the subscription_relationship column
if ( 'subscription_relationship' !== $column_name ) {
return;
}
// Check if we're on the subscriptions tab
if ( isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'] ) {
// Make sure this is a subscription
if ( 'shop_subscription' === $order->get_type() ) {
$subscription = wcs_get_subscription( $order->get_id() );
if ( $subscription ) {
// Get subscription details
$start_date = $subscription->get_date_to_display( 'start' );
$end_date = $subscription->get_date_to_display( 'end' );
// Get order count
$related_orders = $subscription->get_related_orders();
$order_count = count( $related_orders );
// Build the details HTML
echo '<div class="subscription-details">';
echo '<p><strong>' . esc_html__( 'Start Date:', 'simple-subscriptions-ui' ) . '</strong> ' . esc_html( $start_date ) . '</p>';
echo '<p><strong>' . esc_html__( 'End Date:', 'simple-subscriptions-ui' ) . '</strong> ' . esc_html( $end_date ? $end_date : __( 'N/A', 'simple-subscriptions-ui' ) ) . '</p>';
echo '<p><strong>' . esc_html__( 'Order Count:', 'simple-subscriptions-ui' ) . '</strong> ' . esc_html( $order_count ) . '</p>';
echo '</div>';
// Prevent the default column content from being displayed
return;
}
}
}
}
/**
* Remove the default subscription relationship column content when in the Subscriptions view.
*/
public function maybe_remove_default_subscription_column_content() {
// Check if we're on the WooCommerce Orders screen and in the Subscriptions view
if ( isset( $_GET['page'] ) && 'wc-orders' === $_GET['page'] && isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'] ) {
// Remove the default subscription relationship column content
remove_action( 'woocommerce_shop_order_list_table_custom_column', array( 'WC_Subscriptions_Order', 'add_contains_subscription_column_content_orders_table' ), 10 );
}
}
/**
* Add CSS to hide the default subscription relationship column content when in the Subscriptions view.
*/
public function add_subscription_details_css() {
// Check if we're on the WooCommerce Orders screen and in the Subscriptions view
if ( isset( $_GET['page'] ) && 'wc-orders' === $_GET['page'] && isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'] ) {
// Add CSS to hide the default subscription relationship column content
?>
<style type="text/css">
/* Hide the default subscription relationship column content */
.subscription_renewal_order,
.subscription_resubscribe_order,
.subscription_parent_order,
.normal_order {
display: none !important;
}
</style>
<?php
}
}
/**
* Remove the WooCommerce Subscriptions admin screen.
*/
public function remove_subscriptions_admin_screen() {
// Remove the action that registers the Subscriptions admin screen in the WC Admin
remove_action( 'init', array( 'WCS_WC_Admin_Manager', 'init' ), 11 );
// Add a filter to modify the subscription post type registration to hide it from the admin menu
add_filter( 'woocommerce_register_post_type_subscription', array( $this, 'hide_subscription_menu_item' ), 20 );
// Remove the admin_menu actions from WCS_WC_Admin_Manager
add_action( 'admin_menu', array( $this, 'remove_subscription_admin_menu' ), 5 );
}
/**
* Remove the subscription admin menu items.
*/
public function remove_subscription_admin_menu() {
// Remove the actions that register the subscription admin pages
remove_action( 'admin_menu', array( 'WCS_WC_Admin_Manager', 'register_subscription_admin_pages' ) );
remove_action( 'admin_menu', array( 'WCS_WC_Admin_Manager', 'register_navigation_items' ), 6 );
// Add a late action to remove the menu item directly
add_action( 'admin_menu', array( $this, 'remove_subscription_menu_item' ), 999 );
}
/**
* Remove the subscription menu item directly.
*/
public function remove_subscription_menu_item() {
global $menu, $submenu;
// Remove the Subscriptions submenu from WooCommerce menu
if ( isset( $submenu['woocommerce'] ) ) {
foreach ( $submenu['woocommerce'] as $key => $menu_item ) {
// Check if this is the Subscriptions menu item
if ( isset( $menu_item[2] ) &&
( $menu_item[2] === 'edit.php?post_type=shop_subscription' ||
$menu_item[2] === 'admin.php?page=wc-orders--shop_subscription' ) ) {
unset( $submenu['woocommerce'][$key] );
}
}
}
// Also check for top-level menu item (if user doesn't have manage_woocommerce capability)
if ( isset( $menu ) && is_array( $menu ) ) {
foreach ( $menu as $key => $menu_item ) {
if ( isset( $menu_item[2] ) &&
( $menu_item[2] === 'edit.php?post_type=shop_subscription' ||
$menu_item[2] === 'admin.php?page=wc-orders--shop_subscription' ) ) {
unset( $menu[$key] );
}
}
}
}
/**
* Hide the subscription menu item from the admin menu.
*
* @param array $args The post type registration arguments.
* @return array Modified arguments.
*/
public function hide_subscription_menu_item( $args ) {
// Set show_in_menu to false to hide it from the admin menu
$args['show_in_menu'] = false;
return $args;
}
/**
* Add CSS to hide the Subscriptions menu item as a fallback.
*/
public function hide_subscription_menu_css() {
?>
<style type="text/css">
/* Hide the Subscriptions menu item */
#adminmenu a[href="edit.php?post_type=shop_subscription"],
#adminmenu a[href="admin.php?page=wc-orders--shop_subscription"],
#woocommerce-subscriptions,
#woocommerce-custom-orders-subscriptions,
li.toplevel_page_wc-orders--shop_subscription {
display: none !important;
}
</style>
<?php
}
/**
* Add Subscriptions tab to WooCommerce Orders screen.
*
* @param array $view_links Array of view links.
* @return array Modified array of view links.
*/
public function add_subscriptions_tab_to_orders_screen( $view_links ) {
// Get the count of subscriptions
$subscription_count = 0;
// If WooCommerce Subscriptions is active, try to get the actual count
if ( class_exists( 'WC_Subscriptions' ) ) {
// Get all subscription statuses
$subscription_statuses = array();
if ( function_exists( 'wcs_get_subscription_statuses' ) ) {
$subscription_statuses = array_keys( wcs_get_subscription_statuses() );
}
$counts = wp_count_posts( 'shop_subscription' );
if ( $counts ) {
// Count all subscriptions with valid statuses
$subscription_count = 0;
foreach ( (array) $counts as $status => $count ) {
// Skip trash status
if ( 'trash' === $status ) {
continue;
}
// Include all subscription statuses
if ( empty( $subscription_statuses ) || in_array( 'wc-' . $status, $subscription_statuses ) || in_array( $status, $subscription_statuses ) ) {
$subscription_count += $count;
}
}
}
}
// Get current status from request
$current = isset( $_GET['type'] ) && 'subscriptions' === $_GET['type'];
// Add the Subscriptions tab
$view_links['subscriptions'] = sprintf(
'<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
admin_url( 'admin.php?page=wc-orders&type=subscriptions' ),
$current ? 'current' : '',
__( 'Subscriptions', 'simple-subscriptions-ui' ),
number_format_i18n( $subscription_count )
);
return $view_links;
}
}
/**
* Returns the main instance of Simple_Subscriptions_UI.
*
* @return Simple_Subscriptions_UI
*/
function Simple_Subscriptions_UI() {
return Simple_Subscriptions_UI::instance();
}
// Initialize the plugin
Simple_Subscriptions_UI();
// Register activation hook
register_activation_hook( __FILE__, 'simple_subscriptions_ui_activate' );
/**
* Plugin activation callback.
*/
function simple_subscriptions_ui_activate() {
// Activation code here if needed
}
// Register deactivation hook
register_deactivation_hook( __FILE__, 'simple_subscriptions_ui_deactivate' );
/**
* Plugin deactivation callback.
*/
function simple_subscriptions_ui_deactivate() {
// Deactivation code here if needed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment