Skip to content

Instantly share code, notes, and snippets.

@imath
Last active August 5, 2024 13:19
Show Gist options
  • Save imath/2b6d2ce1ead6aba11c8ad12c6beb4770 to your computer and use it in GitHub Desktop.
Save imath/2b6d2ce1ead6aba11c8ad12c6beb4770 to your computer and use it in GitHub Desktop.
Using WP Statuses for custom Post Types.
<?php
/**
* Using WP Statuses for custom Post Types.
*
* @link http://github.com/imath/wp-statuses
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* Register the 'ticket' Post Type and the ticket's specific statuses.
*
* @link http://codex.wordpress.org/Function_Reference/register_post_type
*/
function example_register() {
register_post_type( 'ticket', array(
'labels' => array(
'name' => _x( 'Tickets', 'post type general name', 'plugin-domain' ),
'singular_name' => _x( 'Ticket', 'post type singular name', 'plugin-domain' ),
'menu_name' => _x( 'Tickets', 'admin menu', 'plugin-domain' ),
'name_admin_bar' => _x( 'Ticket', 'add new on admin bar', 'plugin-domain' ),
'add_new' => _x( 'Add new', 'book', 'plugin-domain' ),
'add_new_item' => __( 'Add a new Ticket', 'plugin-domain' ),
'new_item' => __( 'New Ticket', 'plugin-domain' ),
'edit_item' => __( 'Edit Ticket', 'plugin-domain' ),
'view_item' => __( 'View Ticket', 'plugin-domain' ),
'all_items' => __( 'All Tickets', 'plugin-domain' ),
'search_items' => __( 'Search Tickets', 'plugin-domain' ),
'parent_item_colon' => __( 'Parent Ticket:', 'plugin-domain' ),
'not_found' => __( 'No tickets found', 'plugin-domain' ),
'not_found_in_trash' => __( 'No tickets found in trash', 'plugin-domain' ),
'insert_into_item' => __( 'Insert into ticket', 'plugin-domain' ),
'uploaded_to_this_item' => __( 'Uploaded to this ticket', 'plugin-domain' ),
'filter_items_list' => __( 'Filter tickets list', 'plugin-domain' ),
'items_list_navigation' => __( 'Tickets list navigation', 'plugin-domain' ),
'items_list' => __( 'Tickets list', 'plugin-domain' ),
),
'description' => __( 'WP Statuses\' example for a custom Post Type.', 'plugin-domain' ),
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'tickets' ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'menu_icon' => 'dashicons-tickets',
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
'delete_with_user' => true,
'can_export' => true,
'show_in_rest' => true,
) );
/** Statuses ******************************************************************/
register_post_status( 'resolved', array(
'label' => _x( 'Resolved', 'post status label', 'plugin-domain' ),
'public' => true,
'label_count' => _n_noop( 'Resolved <span class="count">(%s)</span>', 'Resolved <span class="count">(%s)</span>', 'plugin-domain' ),
'post_type' => array( 'ticket' ), // Define one or more post types the status can be applied to.
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'show_in_metabox_dropdown' => true,
'show_in_inline_dropdown' => true,
'dashicon' => 'dashicons-yes',
) );
register_post_status( 'invalid', array(
'label' => _x( 'Invalid', 'post status label', 'plugin-domain' ),
'public' => true,
'label_count' => _n_noop( 'Invalid <span class="count">(%s)</span>', 'Invalids <span class="count">(%s)</span>', 'plugin-domain' ),
'post_type' => array( 'ticket' ), // Define one or more post types the status can be applied to.
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'show_in_metabox_dropdown' => true,
'show_in_inline_dropdown' => true,
'dashicon' => 'dashicons-dismiss',
) );
register_post_status( 'assigned', array(
'label' => _x( 'Assigned', 'post status label', 'plugin-domain' ),
'public' => true,
'label_count' => _n_noop( 'Assigned <span class="count">(%s)</span>', 'Assigned <span class="count">(%s)</span>', 'plugin-domain' ),
'post_type' => array( 'ticket' ), // Define one or more post types the status can be applied to.
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'show_in_metabox_dropdown' => true,
'show_in_inline_dropdown' => true,
'dashicon' => 'dashicons-businessman',
) );
}
add_action( 'init', 'example_register' );
/**
* Only keep Draft & Pending statuses but do not use other builtin statuses.
*
* PS: you should at least keep Draft & Pending.
*
* @param array $post_types The list of registered Post Types for the status.
* @param string $status_name Name of the status to apply to Post Types.
* @return array The list of registered Post Types for the status.
*/
function example_restrict_statuses_for_tickets( $post_types = array(), $status_name = '' ) {
if ( 'draft' === $status_name || 'pending' === $status_name ) {
return $post_types;
}
// All other statuses (eg: Publish, Private...) won't be applied to tickets
return array_diff( $post_types, array( 'ticket' ) );
}
add_filter( 'wp_statuses_get_registered_post_types', 'example_restrict_statuses_for_tickets', 10, 2 );
/**
* Makes sure we can directly "Publish" using custom statuses.
*
* @param array $data A list of arguments to use to insert a new Post Type's item.
* @param array $postarr WordPress' version of posted var.
* @return array A list of arguments to use to insert a new Post Type's item.
*/
function example_insert_using_custom_status( $data = array(), $postarr = array() ) {
if ( empty( $postarr['publish'] ) ) {
return $data;
}
if ( 'ticket' !== $data['post_type'] ) {
return $data;
}
if ( ! empty( $postarr['_wp_statuses_status'] ) && in_array( $postarr['_wp_statuses_status'], array(
'resolved',
'invalid',
'assigned',
), true ) ) {
$data['post_status'] = sanitize_key( $postarr['_wp_statuses_status'] );
// Default status for the tickets Post Type is assigned.
} else {
$data['post_status'] = 'assigned';
}
return $data;
}
add_filter( 'wp_insert_post_data', 'example_insert_using_custom_status', 10, 2 );
@garretthyder
Copy link

Thanks @imath, this is a life-saver

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment