カスタムフィールド、カスタムタクソノミーを持つカスタム投稿タイプをクラス化する : WordPress

Pocket

カスタムフィールド、カスタムタクソノミー設定可能なカスタム投稿タイプのクラスを作成するメモ。
下記サイトを参考にfunctions.phpとcustom_post_type.phpを作成する。

» Custom Post Type Helper Class | Wptuts+

function.php

CustomPostTypeクラス作成しカスタムタクソノミー、カスタムフィールドを追加する。

<?php
....
include( get_template_directory() . '/custom_post_type.php' );
// custom post type
$custom = new CustomPostType( 'my_post_type', array() );
$custom->addTaxonomy( 'may_taxonomy');
$custom->addMetabox(
    'my_meta_box',
    array(
        'name' => 'text',
        'nationality' => 'text',
    )
);

custom_post_type.php

<?php
/**
 * CustomPostType class
 *
 * @author Sawai Hiroshi
 */

/**
 * CustomPostType
 */
class CustomPostType
{

    /** @var string $post_type_name custom post type name */
    public $post_type_name;
    /** @var array $labels label of custom post type */
    public $labels;

    /**
     * @param string $post_type_name
     * @param array $labels custom post type labels
     */
    public function __construct( $post_type_name, $labels = array() )
    {
        $this->post_type_name =  strtolower( str_replace(' ', '_', $post_type_name ) );
        $this->setLabels( $labels );

        if ( ! post_type_exists( $this->post_type_name ) ) {
            add_action( 'init', array( &$this, 'register') ); // ---------- 1
        }

        $this->save();
    }

    /**
     * set labels of custom post type
     *
     * @param $labels custom post type labels
     */
    private function setLabels( $labels )
    {
        $this->labels = array_merge(
            array(
                'name'               => 'Custom Post',
                'singular_name'      => 'Custom Post一覧',
                'add_new'            => 'Custom Postを追加',
                'add_new_item'       => 'Custom Postを追加',
                'edit_item'          => 'Custom Postを編集',
                'new_item'           => '新しいCustom Post',
                'view_item'          => 'Custom Postを表示',
                'search_items'       => 'Custom Postを探す',
                'not_found'          => 'Custom Postはありません',
                'not_found_in_trash' => 'ゴミ箱にCustom Postはありません',
            ),
            $labels
        );
    }

    /**
     * add custom taxonomy to custom post type
     *
     * @param $name taxonomy name
     * @param array $args register_taxonomy third parameter array
     */
    public function addTaxonomy( $name, $args = array() )
    {
        if ( ! true === empty( $name ) ) {
            $post_type_name   = $this->post_type_name;
            $taxonomy_name    = strtolower( str_replace(' ', '_', $post_type_name ) );
            $taxonomy_args    = $this->setTaxonomyArgs( $args );
        }

        if ( ! true === taxonomy_exists( $name ) ) {
            // register taxonomy
            add_action(
                'init',
                function() use( $taxonomy_name, $post_type_name, $taxonomy_args ) // ----------- 2
                {
                    register_taxonomy( $taxonomy_name, $post_type_name, $taxonomy_args );
                }
            );
        } else {
            add_action(
                'init',
                function() use( $taxonomy_name, $post_type_name )
                {
                    register_taxonomy_for_object_type( $taxonomy_name, $post_type_name );
                }
            );
        }
    }

    /**
     * set custom taxonomy arguments from labels
     *
     * @param  array $args custom taxonomy array of register_taxonomy third parameter
     * @return array custom taxonomy new argument array
     */
    private function setTaxonomyArgs( $args )
    {
        return array_merge(
            array(
                'label'                 => 'Custom Taxonomy',
                'singular_label'        => 'Custom Taxonomy',
                'hierarchical'          => false,
                'update_count_callback' => '_update_post_term_count',
            ),
            $args
        );
    }

    /**
     * add meta box to custom post type
     *
     * @param string $title custom meta box title
     * @param array  $fields field of custom meta box
     * @param string $context
     * @param string $priority
     */
    public function addMetabox( $title, $fields = array(), $context = 'normal', $priority = 'default')
    {
        if ( ! true === empty( $title ) ) {
            $post_type_name   = $this->post_type_name;
            $box_id           = strtolower( str_replace( ' ', '_', $title ) );
            $box_title        = ucwords( str_replace( '_', ' ', $title ) );
            $box_context      = $context;
            $box_priority     = $priority;

            global $custom_fields;
            $custom_fields[ $title ] = $fields;

            add_action(
                'admin_init',
                function() use( $box_id, $box_title, $post_type_name, $box_context, $box_priority, $fields )
                {
                    add_meta_box(
                        $box_id,
                        $box_title,
                        function( $post, $data )
                        {
                            global $post;
                            wp_nonce_field( 'save', 'meta_box' );
                            $custom_fields = $data[ 'args' ][ 0 ];
                            $meta = get_post_custom( $post->ID );

                            // Check the array and loop through it
                            if( ! true === empty( $custom_fields ) )
                            {
                                /* Loop through $custom_fields */
                                foreach( $custom_fields as $label => $type )
                                {
                                    $field_id_name  = strtolower( str_replace( ' ', '_', $data[ 'id' ] ) )
                                                    . '_' . strtolower( str_replace( ' ', '_', $label ) );

                                    if ( true === isset( $meta[ $field_id_name ][ 0 ] ) ) {
                                        $value = $meta[ $field_id_name ][ 0 ];
                                    } else {
                                        $value = '';
                                    }
                                    echo '<label for="' . $field_id_name . '">' . $label
                                       . '</label><input type="text" name="custom_meta[' . $field_id_name . ']" id="'
                                       . $field_id_name . '" value="' . $value  . '" />';
                                }
                            }

                        },
                        $post_type_name,
                        $box_context,
                        $box_priority,
                        array( $fields )
                    );
                }
            );
        }
    }

    /**
     * save custom post type fields
     */
    private function save()
    {
        $post_type_name = $this->post_type_name;
        add_action(
            'save_post',
            function() use( $post_type_name )
            {
                if( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
                    return;
                }

                if ( false === isset( $_POST[ 'meta_box' ] ) ) {
                    return;
                }
                if ( ! wp_verify_nonce( $_POST[ 'meta_box' ], 'save' ) ) {
                    return;
                }
                global $post;
                if( isset( $_POST )
                    && isset( $post->ID )
                    && get_post_type( $post->ID ) === $post_type_name )
                {
                    global $custom_fields;

                    // Loop through each meta box
                    foreach( $custom_fields as $title => $fields )
                    {
                        // Loop through all fields
                        foreach( $fields as $label => $type )
                        {
                            $field_id_name  = strtolower( str_replace( ' ', '_', $title ) ) . '_' . strtolower( str_replace( ' ', '_', $label ) );
                            update_post_meta( $post->ID, $field_id_name, $_POST['custom_meta'][$field_id_name] );
                        }

                    }
                }

            }
        );
    }

    /**
     * register custom post type
     * not private but public
     */
    public function register()
    {
        $args = array(
            'labels'               => $this->labels,
            'public'               => true,
            'capability_type'      => 'post',
            'show_ui'              => true,
            'hierarchical'         => false,
            'supports'             => array( 'title', 'editor', 'thumbnail' ),
            'rewrite'              => array( 'slug' => $this->post_type_name, 'with_front' =>false ),
        );
        register_post_type( $this->post_type_name, $args );
    }

}

メモ

  1. アクションフックのコールバックをこのように指定できることを知った。
  2. アクションフックのコールバック関数にクロージャーを指定する

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。