WordPress custom search for custom post type

After creating a custom post type for an Inventory plugin the client needed also customized search for the columns.

Custom search for custom post type

First the pre_get_posts looked as a good candidate for hooking, but ended up with filtering via posts_clauses_request

add_filter('posts_clauses_request', 'customSearchClause');
function customSearchClause($query)
{
    global $wp_query;

    if (!is_search()) {
        return $query;
    }

    $term = $wp_query->query['s'];
    $query['join'] = 'INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)';
    $query['where'] = "AND wp_posts.post_type = '$this->post_type'
    AND (
        (wp_posts.post_title LIKE '%{$term}%')
        OR (wp_postmeta.meta_key = 'product' AND wp_postmeta.meta_value LIKE '%{$term}%')
        OR (wp_postmeta.meta_key = 'product_code' AND wp_postmeta.meta_value LIKE '%{$term}%')
    )";

    return $query;
}

Adding settings page to a custom post type

I had some struggles with this and now I describe how to do it and what helped me figure out my problem.

1. Register custom post type

First we need to register the desired custom post type.
http://codex.wordpress.org/Function_Reference/register_post_type#Example

add_action( 'init', 'cpt_payment' );
function cpt_payment() {
    $args = array( ... );
    register_post_type( 'payment', $args );
}

2. Add submenu

http://codex.wordpress.org/Function_Reference/add_submenu_page#Example

    function payment_settings() {

        /*
         * Add a settings page for this plugin to the custom post type menu.
         *
         * NOTE:  Alternative menu locations are available via WordPress administration menu functions.
         *
         *        Administration Menus: http://codex.wordpress.org/Administration_Menus
         *
         *   For reference: http://codex.wordpress.org/Roles_and_Capabilities
         */
        add_submenu_page(
            "edit.php?post_type=payment",
            'Payment settings',
            'Settings',
            'manage_options',
            "payment-settings",
            'show_settings_admin_page'
        );

    }
    add_action( 'admin_menu', 'payment_settings' ) );

The take away

I had a different post_type parameter value in add_submenu_page first argument, that’s why the submenu didn’t appear.
To figure this out I echoed the generated submenu in wp-admin/includes/plugin.php of add_submenu_page function.

// wp-admin/includes/plugin.php
1133     $submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );
1134     echo "<pre>"; print_r($submenu); echo "</pre>";exit;

And the output snippet of that debug line:

Array
(
    [index.php] => Array
        (
            [0] => Array
                (
                    [0] => Home
                    [1] => read
                    [2] => index.php
                )

            [10] => Array
                (
                    [0] => Updates 0
                    [1] => update_core
                    [2] => update-core.php
                )

        )

    [edit.php] => Array
        (
            [5] => Array
                (
                    [0] => All Posts
                    [1] => edit_posts
                    [2] => edit.php
                )

            [10] => Array
                (
                    [0] => Add New
                    [1] => edit_posts
                    [2] => post-new.php
                )

            [15] => Array
                (
                    [0] => Categories
                    [1] => manage_categories
                    [2] => edit-tags.php?taxonomy=category
                )

            [16] => Array
                (
                    [0] => Tags
                    [1] => manage_categories
                    [2] => edit-tags.php?taxonomy=post_tag
                )

        )
    [edit.php?post_type=payment] => Array
        (
            [5] => Array
                (
                    [0] => All Payments
                    [1] => edit_posts
                    [2] => edit.php?post_type=payment
                )

            [11] => Array
                (
                    [0] => Settings
                    [1] => manage_options
                    [2] => payment-settings
                    [3] => Payments settings
                )

        )

After seeing that output I saw the solution.
Hope it helps others. For me it was a learning bomb better understaing a code block from WP.

Custom post type Settings subpage

Special thanks to:

http://www.billrobbinsdesign.com/custom-post-type-admin-page/

http://justintadlock.com/archives/2010/04/29/custom-post-types-in-wordpress