WP Manifestindependent plugin directory
0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/jcollings/jc-search/archive/refs/heads/main.zip

JC Search allow you to search WordPress posts, custom fields, taxonomies and user data, adding order weights per attribute.

Table of Contents

  1. Register search engine
  2. Register custom table source
  3. Wildcard term search
  4. Enable quoted search
  5. Enable keyword stemming
  6. WP CLI Usage

Register search engine

<?php
add_filter('jcs/register_engines', function ($engines) {

    $engine = new \JCLabs\Search\Engine\Engine('default');

    // Search posts
    $post = new \JCLabs\Search\Source\PostTypeSource('post', 'post');
    $engine->add_source($post);

    // Search category archive
    $category = new \JCLabs\Search\Source\TaxonomySource('category', ['category', 'post_tag']);
    $engine->add_source($category);

    // Search user archive
    $user = new \JCLabs\Search\Source\UserSource('user');
    $engine->add_source($user);

    $engines[$engine->get_id()] = $engine;
    return $engines;
});

Register custom table source

/**
 * Register custom table source
 */
add_action('plugins_loaded', function () {

    class CustomTableSource extends \JCLabs\Search\Source\Source
    {
        protected $_table_name;

        public function __construct()
        {
            /**
             * @var \WPDB $wpdb
             */
            global $wpdb;

            $this->_table_name = $wpdb->prefix . 'jet_cct_members';

            $this->add_attribute(new \JCLabs\Search\Attribute\FieldAttribute('first_name', 'First Name'));
            $this->add_attribute(new \JCLabs\Search\Attribute\FieldAttribute('last_name', 'Last Name'));
            $this->add_attribute(new \JCLabs\Search\Attribute\FieldAttribute('bio', 'Bio'));

            add_filter('jcs/query/result/post/type=jet_cct_members', function ($data, $id) {

                $entry = $this->get_entry($id);

                $data['post_title'] = $entry->first_name . ' ' . $entry->last_name;
                $data['post_content'] = $entry->bio;

                return $data;
            }, 10, 2);
        }

        /**
         * @param int $paged
         * @return int[]
         */
        public function get_entry_ids($paged = 1)
        {
            /**
             * @var \WPDB $wpdb
             */
            global $wpdb;
            return $wpdb->get_col("SELECT _ID FROM " . $this->_table_name . " LIMIT 100 OFFSET " . ($paged - 1) * 100);
        }

        public function get_index_max_pages()
        {
            /**
             * @var \WPDB $wpdb
             */
            global $wpdb;

            return ceil($wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM " . $this->_table_name, [])) / 100);
        }

        public function get_entry($id)
        {
            /**
             * @var \WPDB $wpdb
             */
            global $wpdb;

            $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $this->_table_name .  " WHERE _ID='%d'", [$id]));

            return $row;
        }

        public function get_type()
        {
            return 'jet_cct_members';
        }

        public function to_post($entry)
        {
            return (object)[
                'ID' => $entry->_ID,
                'post_author' => null,
                'post_date' => '0000-00-00 00:00:00',
                'post_date_gmt' => '0000-00-00 00:00:00',
                'post_content' => $entry->bio,
                'post_title' => $entry->first_name . ' ' . $entry->last_name,
                'post_excerpt' => '',
                'post_status' => 'publish',
                'comment_status' => 'closed',
                'ping_status' => 'closed',
                'post_password' => '',
                'post_name' => '',
                'to_ping' => '',
                'pinged' => '',
                'post_modified' => '0000-00-00 00:00:00',
                'post_modified_gmt' => '0000-00-00 00:00:00',
                'post_content_filtered' => '',
                'post_parent' => 0,
                'guid' => 0,
                'menu_order' => 0,
                'post_type' => '',
                'post_mime_type' => '',
                'comment_count' => 0,
                'jcs_type' => 'jet_cc_members'
            ];
        }
    }
});

add_filter('jcs/register_engines', function ($engines) {

    $engine = new \JCLabs\Search\Engine\Engine('default');

    $table = new CustomTableSource('jet_cc_members');
    $engine->add_source($table);

    $engines[$engine->get_id()] = $engine;

    return $engines;
});

/**
 * Override post_link for custom table
 */
add_filter('jcs/post_link/type=jet_cc_members', function ($link) {
    return site_url('?asd=123');
});

Wildcard term search

add_filter('jcs/query/term_wildcard_prefix', '__return_true');
add_filter('jcs/query/term_wildcard_suffix', '__return_true');

Quoted search

add_filter('jcs/query/quoted_search', '__return_true');

Enable keyword stemming

add_filter('jcs/query/keyword_stemming', '__return_true');

Enable strict mode

Strict mode requires every time you make a change to the engine including weights that the index and schema need to be rebuilt, due to the index table only storing weighted attributes to boost performance and database size.

add_filter('jcs/engine/strict_mode', '__return_true');

Enable Ajax results

add_filter('jcs/ajax_search_input', function () {
    return '.wp-block-search__input';
});

Enable Ajax instant results

add_filter('jcs/ajax_search_type', function () {
    return 'instant';
});

add_filter('jcs/ajax_search_input', function () {
    return '.wp-block-search__input';
});

add_filter('jcs/ajax_instant_template', function ($template, $record, $type) {

    $link = JCS()->query->post_link(get_permalink($record), $record);

    return sprintf('<a href="%s">
        <span>%s</span>
    </a>', $link, $record->post_title);
}, 10, 3);

Enable Debug Log

Log file is output to uploads/jcsearch.txt

add_filter('jcs/log', '__return_true');

WP CLI Usage

Rebuild all engines and index records

wp jcs reset

Reset all engines tables

wp jcs schema

Generate search index

wp jcs index default
wp jcs index --all
wp jcs index default --id=1
wp jcs index --all --id=1