wir
7/20/2017 - 3:45 PM

Using WP Statuses for custom Post Types.

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 );