Codementor Events

A class for setting up Custom Post Types in WordPress

Published Feb 14, 2020
A class for setting up Custom Post Types in WordPress

A class for setting up Custom Post Types in WordPress and making most functions "pluggable" by setting them to fire if they exist in the class which instantiates it.

NOTE: To use in your plugin you will need to hard code or modify this to accept the plugin name. I plan on the edit in the near future but as of this writing I have not made it.

The Class

<?php
/**
 * Created by PhpStorm.
 * User: Bobby
 * Date: 11/26/14
 * Time: 1:30 PM
 * Channel Log:
 * @ V 1.0.0 - 11/26/14
 */
/**
 * Class Set_up_CPT
 * Sets up custom post type and make action functions pluggable through calling obj
 */
class Set_up_CPT
{
    public $post_type; // required arg key - required
    public $post_type_name; // defaults to post type with ucfirst
    public $post_type_name_lc; // defaults to post type with ucfirst
    public $post_type_supports; // see below for defaults
    public $menu_positon; // defaults to 1
    public $exclude_from_search; // defaults to false
    public $show_ui; // defaults to true
    public $show_in_menu; // defaults to true
    public $description; // defaults to empty string
    public $pl_func_class_obj_name; // name of object calling class - required
    public $hierarchical; // defaults to false
    public $has_archive; // defaults to false
    public $map_meta_cap; // defaults to true
    public $query_var; // defaults to true
    public $publicly_queryable; // defaults to public value
    public $menu_icon;

    /**
     * @param $cpt_args - see _set_up_cpt()
     * @param $pl_func_class_name - class instantiating this class
     */
    public function __construct($cpt_args, $pl_func_class_name)
    {
        // Need the post type and caller obj - return false if not set
        if (!$cpt_args['post_type'] || !$pl_func_class_name) return false;
        // get caller obj to set pluggable functions in calling class
        $this->pl_func_class_obj_name = $pl_func_class_name;
        // set up cpt args
        $this->post_type = $cpt_args['post_type'];
        $this->post_type_name = (array_key_exists('post_type_name', $cpt_args)) ? $cpt_args['post_type_name'] : ucfirst($cpt_args['post_type']); // defaults to post type uppercase
        $this->menu_position = (array_key_exists('menu_position', $cpt_args)) ? $cpt_args['menu_position'] : 1;
        $this->exclude_from_search = (array_key_exists('exclude_from_search', $cpt_args)) ? $cpt_args['exclude_from_search'] : false;
        $this->public = (array_key_exists('public', $cpt_args)) ? $cpt_args['public'] : true;
        $this->show_ui = (array_key_exists('show_ui', $cpt_args)) ? $cpt_args['show_ui'] : true;
        $this->show_in_menu = (array_key_exists('show_in_menu', $cpt_args)) ? $cpt_args['show_in_menu'] : true;
        $this->description = (array_key_exists('description', $cpt_args)) ? $cpt_args['description'] : '';
        $this->hierarchical = (array_key_exists('hierarchical', $cpt_args)) ? $cpt_args['hierarchical'] : false;
        $this->map_meta_cap = (array_key_exists('map_meta_cap', $cpt_args)) ? $cpt_args['map_meta_cap'] : true;
        $this->has_archive = (array_key_exists('has_archive', $cpt_args)) ? $cpt_args['has_archive'] : false;
        $this->query_var = (array_key_exists('query_var', $cpt_args)) ? $cpt_args['query_var'] : true;
        $this->menu_icon = (array_key_exists('menu_icon', $cpt_args)) ? $cpt_args['menu_icon'] : 'admin-post';


        $this->post_type_name_lc = strtolower($this->post_type_name);

        // remove all spaces from post type name lc and replace with '_'
        $this->post_type_name_lc = str_replace(' ', '_', $this->post_type_name_lc);
        // if not specified make support all
        if (empty($cpt_args['post_type_supports'])) {
            $this->post_type_supports = array('title', 'editor', 'author', 'custom-fields', 'revisions', 'attachments', 'comments');
        } else {
            $this->post_type_supports = $cpt_args['post_type_supports'];
        }
        $this->heirarchical = strtolower($this->hierarchical);

        // load all actions via pluggable functions
        $this->_set_up_cpt();
        // load function on current_screen to make sure we have screen
        add_action('current_screen', array($this, 'add_cpt_scripts_n_styles'));
    }

    /**
     * @todo - Fix declartion doc for this class
     * Registers Post type creates all labels adds in action and filter functions if they exist pertaining to the post type
     *
     * @param string $post_type - required - the post type
     * @param string $this ->post_type_name - required - the name eg. 'Permit' / 'Job' / 'Survey'
     * @param int $menu_position - recommended - defaults to 1 the position in the menu
     * @param array $post_type_supports - default is all
     *  $post_type_supports = array(
     *   'title',
     *   'editor',
     *   'author',
     *   'custom-fields',
     *   'revisions',
     *   'attachments',
     *   'comments'
     * );
     * @param bool $exclude_from_search - default is false - show in front end results true / false
     * @param bool $public - show in admin - default is true
     * @param bool $show_ui - show in edit screen - default is true
     * @param string $description - description - default is empty string
     * @param string|bool $show_in_menu - where to show menu - default is 1
     *
     * @see register post type for better explanation
     */
    private function _set_up_cpt()
    {
        // set up labels
        $post_type_labels = array(
            'name' => _x('All ' . $this->post_type_name . 's', ''), // Name Displayed On Head
            'singular_name' => _x($this->post_type_name, ''),
            'add_new' => _x('Add New ' . $this->post_type_name, ''),
            'add_new_item' => __('Add New ' . $this->post_type_name),
            'edit_item' => __('Edit ' . $this->post_type_name),
            'new_item' => __('New ' . $this->post_type_name),
            'all_items' => __('All ' . $this->post_type_name . 's'),
            'view_item' => __('View ' . $this->post_type_name),
            'search_items' => __('Search ' . $this->post_type_name . 's'),
            'not_found' => __('Nothing found in ' . $this->post_type_name . 's'),
            'not_found_in_trash' => __('Nothing found in ' . $this->post_type_name . ' Trash'),
            'menu_name' => __($this->post_type_name . 's')
        );
        $post_type_args = array(
            'labels' => $post_type_labels,
            'description' => $this->description . 's',
            'exclude_from_search' => $this->exclude_from_search,
            'public' => $this->public,
            'publicly_queryable' => $this->publicly_queryable,
            'show_ui' => $this->show_ui,
            'show_in_menu' => $this->show_in_menu,
            'query_var' => $this->query_var,
            'rewrite' => array('slug' => $this->post_type_name_lc . 's'),
            'capability_type' => $this->post_type_name_lc,
            'capabilities' => array(
                'publish_posts' => 'publish_' . $this->post_type_name_lc . 's',
                'edit_posts' => 'edit_' . $this->post_type_name_lc . 's',
                'edit_others_posts' => 'edit_others_' . $this->post_type_name_lc . 's',
                'delete_posts' => 'delete_' . $this->post_type_name_lc . 's',
                'delete_others_posts' => 'delete_others_' . $this->post_type_name_lc . 's',
                'read_private_posts' => 'read_private_' . $this->post_type_name_lc . 's',
                'edit_post' => 'edit_' . $this->post_type_name_lc,
                'delete_post' => 'delete_' . $this->post_type_name_lc,
                'read_post' => 'read_' . $this->post_type_name_lc,
            ),
            'map_meta_cap' => $this->map_meta_cap,
            'has_archive' => $this->has_archive,
            'hierarchical' => $this->hierarchical,
            'menu_position' => $this->menu_position,
            'supports' => $this->post_type_supports,
            'menu_icon' => $this->menu_icon
        );
        register_post_type($this->post_type, $post_type_args);
        /*
         * Check for and add actions / filters for all post type specific functions for this post type.
         */
        /**********************
         * WP Hook Pluggable Functions
         ************************/
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_set_cpt_columns')) {
            // use to set custom columns
            add_action('manage_edit-' . $this->post_type . '_columns', array($this->pl_func_class_obj_name, $this->post_type . '_set_cpt_columns')); // call custom if it exists
        } else {
            // calls default columns
            add_action('manage_edit-' . $this->post_type . '_columns', array($this->pl_func_class_obj_name, 'set_cpt_columns'));
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_manage_cpt_columns')) {
            // use to manage data displayed in post type columns
            add_action('manage_' . $this->post_type . '_posts_custom_column', array($this->pl_func_class_obj_name, $this->post_type . '_manage_cpt_columns'), 10, 3);
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_pre_get_cpt')) {
            // use to filter what is displayed for this post types list page
            add_action('pre_get_posts', array($this->pl_func_class_obj_name, $this->post_type . '_pre_get_cpt'), 10);
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_save')) {
            // use for save function
            add_action('save_post_' . $this->post_type, array($this->pl_func_class_obj_name, $this->post_type . '_save'), 10);
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_remove_boxes')) {
            // use to remove any boxes
            add_action('admin_init', array($this->pl_func_class_obj_name, $this->post_type . '_remove_boxes'), 1);
        }
        if (method_exists($this->pl_func_class_obj_name, 'add_meta_boxes_' . $this->post_type)) {
            // use to set up boxes for post type
            add_action('admin_init', array($this->pl_func_class_obj_name, 'add_meta_boxes_' . $this->post_type));
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_post_row_actions')) {
            // use to set up custom post row actions if needed
            add_action('post_row_actions', array($this->pl_func_class_obj_name, $this->post_type . '_post_row_actions'));
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_bulk_actions')) {
            // use to set up custom post bulk actions if needed
            add_action('bulk_actions-edit-' . $this->post_type, array($this->pl_func_class_obj_name, $this->post_type . '_bulk_actions'));
        }
        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_restore_meta_revision')) {
            // use to set up post meta revisioning if needed
            add_action('wp_restore_post_revision', array($this->pl_func_class_obj_name, $this->post_type . '_restore_meta_revision'), 10, 2);
        }

        /**********************
         * Custom Hook Calls - @todo need to be reassed to new design
         ************************/
//        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_task_file_meta')) {
//            // use to alter task meta on upload
//            add_action('rvms_change_task_file_meta', array($this->pl_func_class_obj_name, $this->post_type . '_task_file_meta'), 1, 1); // hook located near line 777 RVMS - 0.0.1 in rvms_client_subcon_job.php
//        }
//        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_pm_and_qc_files_filter')) {
//            // use to alter task meta on upload
//            add_action('rvms_get_pm_and_qc_files_filter', array($this->pl_func_class_obj_name, $this->post_type . '_pm_and_qc_files_filter'), 1, 2); // hook located near line 1539 RVMS - 0.0.1 in meta_box_bainternet.php
//        }
//        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_client_pickup_files_filter')) {
//            // use to alter task meta on upload
//            add_action('rvms_get_client_pickup_files_filter', array($this->pl_func_class_obj_name, $this->post_type . '_client_pickup_files_filter'), 1, 2); // hook located near line 1539 RVMS - 0.0.1 in meta_box_bainternet.php
//        }
//        if (method_exists($this->pl_func_class_obj_name, $this->post_type . '_new_user_filter')) {
//            // use to alter task meta on upload
//            add_action('rvms_user_register', array($this->pl_func_class_obj_name, $this->post_type . '_new_user_filter'), 2); // hook created and placed in core user-new.php - line 424 - RVMS - 0.0.1 WP - 3.8.1
//        }
    }

    /**
     * Used as to add scripts ans styles for post types.
     * Creates a script name spaced $post_type.'_js'
     * for
     * ABSPATH.'js/'.$post_type.'_edit_single.js'
     *
     * Creates a stylesheet name spaced
     * $post_type.'_css'
     * for
     * ABSPATH.'css/'.$post_type.'_edit_single.css'
     *
     * Creates a script name spaced
     * 'all_' . $post_type . 's_screen_js'
     * for
     * ABSPATH.'js/all_' . $post_type . 's_screen.js
     *
     * Creates a stylesheet name spaced
     * 'all_' . $post_type . 's_screen_js'
     * for
     * ABSPATH.'css/all_' . $post_type . 's_screen.css'     *
     *
     * @param $post_type - the post type - needed to tell what post type and also used in all naming or the styles and scripts
     */
    public function add_cpt_scripts_n_styles()
    {
        $screen = get_current_screen();
        // All $this->post_type screen
        if ($screen->id === 'edit-' . $this->post_type) {
            // script
            $js = 'all_' . $this->post_type . 's_screen_js';
            $js_path = ABSPATH . 'wp-content/plugins/rvms/js/all_' . $this->post_type . 's_screen.js';
            $js_url = 'wp-content/plugins/rvms/js/all_' . $this->post_type . 's_screen.js';
            // enqueue only if exists
            if (file_exists($js_path)) {
                add_action('admin_enqueue_scripts',
                    function () use ($js, $js_path) {
                        wp_enqueue_script($js, $js_path, 1, true);
                    });
            }

            // style
            $stylesheet = 'all_' . $this->post_type . '_css';
            $stylesheet_path = ABSPATH . 'wp-content/plugins/rvms/js/css/all_' . $this->post_type . 's_screen.css';
            // enqueue only if exists
            if (file_exists($stylesheet_path)) {
                add_action('admin_enqueue_scripts',
                    function () use ($stylesheet, $stylesheet_path) {
                        wp_enqueue_style($stylesheet, $stylesheet_path);
                    });
            }
        } else // If in single $this->post_type view
            if ($screen->id === $this->post_type) {
                // script
                $js = $this->post_type . '_edit_single_js';
                /**@TODO MODIFY TO YOUR PATH **/
                $js_path = ABSPATH . 'wp-content/plugins/rvms/js/' . $this->post_type . '_edit_single.js';
                 /**@TODO MODIFY TO YOUR PATH **/
                $js_url = home_url('wp-content/plugins/rvms/js/' . $this->post_type . '_edit_single.js');
                // enqueue only if exists
                if (file_exists($js_path)) wp_enqueue_script($js, $js_url, 1, true);

                // style
                $stylesheet = $this->post_type . '_css';
                 /**@TODO MODIFY TO YOUR PATH **/
                $stylesheet_path = ABSPATH . 'wp-content/plugins/rvms/css/' . $this->post_type . '_edit_single.css';
                 /**@TODO MODIFY TO YOUR PATH **/
                $stylesheet_url = home_url('wp-content/plugins/rvms/css/' . $this->post_type . '_edit_single.css');
                // enqueue only if exists
                if (file_exists($stylesheet_path)) wp_enqueue_style($stylesheet, $stylesheet_url, 1, true);
            }
    }
} 

The Most Updated Version

The Gist

Discover and read more posts from Robert Ruby
get started