SearchWP for BuddyBoss
Upload and activate Search WP
Enable a Supplemental Engine
Add Buddypress and bbPress extensions
Add custom code to enable BuddyPress activity entries
get the source here: https://gist.github.com/jchristopher/7f5d249fddaa6c09d5792879529398c2
<?php
/**
* Custom SearchWP Source for BuddyPress Activity.
* NOTE: Requires SearchWP 4
*/
add_action( 'plugins_loaded', function() {
// if ( ! class_exists( '\SearchWP\Source' ) || ! function_exists( 'bp_activity_get' ) ) {
// return;
// }
class BuddyPressActivity extends \SearchWP\Source {
protected $name = 'buddypressactivity';
protected $db_id_column = 'id';
function __construct() {
global $wpdb;
$this->db_table = $wpdb->base_prefix . 'bp_activity';
$this->labels = [
'plural' => 'BuddyPress Activity',
'singular' => 'BuddyPress Activity',
];
$this->attributes = [ [
'name' => 'content',
'label' => 'Content',
'default' => \SearchWP\Utils::get_min_engine_weight(),
'data' => function( $entry_id ) {
$content = '';
$entry = bp_activity_get( [ 'in' => [ $entry_id ] ] );
if ( ! empty( $entry['activities'] ) ) {
$content = $entry['activities'][0]->content;
}
return $content;
},
], ];
}
// Restrict to Activity updates.
protected function db_where() {
return [ [
'column' => 'component',
'value' => 'activity',
] ];
}
// Return results of bp_activity_get() for this Activity entry.
public function entry( \SearchWP\Entry $entry, $query = false ) {
return bp_activity_get( [ 'in' => [ $entry->get_id() ] ] );
}
}
add_filter( 'searchwp\sources', function( $sources ) {
$sources[] = new BuddyPressActivity();
return $sources;
} );
} );
Add custom code to enable BuddyPress XProfile Fields as a source
<?php
use SearchWP\Entry;
use SearchWP\Source;
use SearchWP\Utils;
use SearchWP\Option;
use SearchWP\Settings;
function dlog($message, $shouldNotDie = true)
{
error_log(print_r($message, true));
}
add_action( 'plugins_loaded', function() {
// if ( ! class_exists( '\SearchWP\Source' ) || ! function_exists( 'bp_activity_get' ) ) {
// return;
// }
class BuddyPressUserXprofile extends \SearchWP\Source {
protected $name = 'buddybossuserxprofile';
protected $db_id_column = 'id';
function __construct() {
global $wpdb;
$this->db_table = $wpdb->base_prefix . 'users';
$bp_fields_table = $wpdb->prefix . 'bp_xprofile_fields';
$delimiter = '_';
//write_log($bp_fields_table);
$this->labels = [
'plural' => 'BuddyPress Users',
'singular' => 'BuddyPress User',
];
$fields = $wpdb->get_results("SELECT * FROM {$bp_fields_table}");
//write_log($fields);
$attributes = array();
foreach ( $fields as $field ) {
//generate slug for searchwp
$bp_user_attribute_slug = strtolower(trim(preg_replace('/[\s-]+/', $delimiter, preg_replace('/[^A-Za-z0-9-]+/', $delimiter, preg_replace('/[&]/', 'and', preg_replace('/[\']/', '', iconv('UTF-8', 'ASCII//TRANSLIT', $field->name))))), $delimiter));
$bp_user_attribute_name = $field->name;
//write_log($bp_user_attribute_name);
$attributes[] = [
'name' => $bp_user_attribute_slug,
'label' => $bp_user_attribute_name,
'default' => \SearchWP\Utils::get_min_engine_weight(),
'data' => function( $user_id ) use ($bp_user_attribute_name) {
//$field_id = xprofile_get_field_id_from_name($bp_user_attribute_slug);
//return xprofile_get_field_data($bp_user_attribute_slug, $user_id);
return bp_get_member_profile_data(
array(
'field'=>$bp_user_attribute_name,
'user_id' => $user_id
)
);
},
];
}
$this->attributes = $attributes;
}
public function entry( \SearchWP\Entry $entry, $query = false ) {
$user = get_user_by( 'id', $entry->get_id() );
return $user;
}
}
add_filter( 'searchwp\sources', function( $sources ) {
$sources[] = new BuddyPressUserXprofile();
//write_log(count($sources));
return $sources;
//[09-Sep-2022 03:28:11 UTC] WordPress database error Table 'askoneguidestg_1657318144.wp_2_users' doesn't exist for query SELECT SQL_CALC_FOUND_ROWS wp_2_users.id FROM wp_2_users WHERE 1=1 LIMIT 1 made by do_action('wp_ajax_searchwp_index_stats'), WP_Hook->do_action, WP_Hook->apply_filters, SearchWP\Index\Controller->_index_stats, SearchWP\Index\Controller->get_stats, SearchWP\Index\Controller->get_count_entries, SearchWP\Source->get_entry_db_records
} );
if(function_exists('bbp_get_user_profile_url')){
add_filter( 'author_link', function( $link, $author_id, $author_nicename){
$link = bbp_get_user_profile_url($author_id);
return $link;
},10,3);
}
} );
if (!function_exists('write_log')) {
function write_log($log) {
if (true === WP_DEBUG) {
if (is_array($log) || is_object($log)) {
error_log(print_r($log, true));
} else {
error_log($log);
}
}
}
}
Configure searchwp sources for the supplemental engine
Create Search template and add to your child theme
<?php
/* Template Name: SearchWP Results */
global $post;
// Retrieve applicable query parameters.
$search_query = isset( $_GET['searchwp'] ) ? sanitize_text_field( $_GET['searchwp'] ) : null;
$search_page = isset( $_GET['swppg'] ) ? absint( $_GET['swppg'] ) : 1;
// Perform the search.
$search_results = [];
$search_pagination = '';
if ( ! empty( $search_query ) && class_exists( '\\SearchWP\\Query' ) ) {
$searchwp_query = new \SearchWP\Query( $search_query, [
'engine' => 'supplemental', // The Engine name.
'fields' => 'all', // Load proper native objects of each result.
'page' => $search_page,
] );
$search_results = $searchwp_query->get_results();
$search_pagination = paginate_links( array(
'format' => '?swppg=%#%',
'current' => $search_page,
'total' => $searchwp_query->max_num_pages,
) );
}
get_header(); ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<header class="page-header">
<h1 class="page-title">
<?php if ( ! empty( $search_query ) ) : ?>
<?php printf( __( 'Search Results for: %s' ), esc_html( $search_query ) ); ?>
<?php else : ?>
SearchWP Supplemental Search
<?php endif; ?>
</h1>
<!-- BEGIN Supplemental Engine Search form -->
<form role="search" method="get" class="search-form"
action="<?php echo site_url( 'search-results/' ); ?>">
<label>
<span class="screen-reader-text">
<?php echo _x( 'Search for:', 'label' ) ?>
</span>
<input type="search" class="search-field"
name="searchwp"
placeholder="<?php echo esc_attr_x( 'Search...', 'placeholder' ) ?>"
value="<?php echo isset( $_GET['searchwp'] ) ? esc_attr( $_GET['searchwp'] ) : '' ?>"
title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
</label>
<input type="submit" class="search-submit"
value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>
<!-- END Supplemental Engine Search form -->
</header>
<?php if ( ! empty( $search_query ) && ! empty( $search_results ) ) : ?>
<?php foreach ( $search_results as $search_result ) : ?>
<article class="page hentry search-result">
<?php
switch( get_class( $search_result ) ) {
case 'WP_Post':
$post = $search_result;
?>
<div class="entry-wrap">
<div class="entry-thumb-col">
<a href="<?php echo get_permalink(); ?>">
<?php if ( has_post_thumbnail() ) {
the_post_thumbnail('thumbnail');}
if ( !has_post_thumbnail() ) {
$entry_image_id = intval(get_post_meta( get_the_ID(), 'expert-profile-image', true));
if ($entry_image_id) {
$entry_image = wp_get_attachment_image_src($entry_image_id, 'medium');
if ($entry_image) {
?><img width="150" height="150" src="<?php echo $entry_image[0]; ?>" /><?php
}
}
if ( $entry_image_id==0 ) {
?>
<img width="150" height="150" src="<?php echo bp_search_get_post_thumbnail_default( get_post_type($search_result->data->ID) ) ?>" />
<?php }} ?>
</a></div>
<div class="entry-content-col">
<header class="entry-header"><h2 class="entry-title">
<a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a>
</h2></header>
<div class="entry-summary"><a href="<?php echo get_permalink(); ?>"><?php the_excerpt(); ?><?php echo get_post_meta(get_the_ID(), 'expert-bio', true); ?></a></div>
</div></div>
<?php
wp_reset_postdata();
break;
case 'WP_User':
?>
<div class="entry-wrap">
<div class="entry-thumb-col">
<a href="<?php echo bbp_get_user_profile_url( $search_result->data->ID ); ?>">
<?php echo get_avatar( $search_result->data->ID, 150 ); ?>
</a></div>
<div class="entry-content-col">
<header class="entry-header"><h2 class="entry-title">
<a href="<?php echo bbp_get_user_profile_url( $search_result->data->ID ); ?>">
<?php echo esc_html( $search_result->data->display_name ); ?>
</a>
</h2></header>
<div class="entry-summary">
<div class="member-custom-field-directory">
<?php $xprofile_company = xprofile_get_field_data( 'Company Name', $search_result->data->ID );
echo xprofile_get_field_data( 'Title', $search_result->data->ID ) ;
if ($xprofile_company) {
echo " at ".$xprofile_company;
}
?>
</div>
<?php echo wp_kses_post( get_the_author_meta( 'description',
$search_result->data->ID ) ); ?>
</div></div></div>
<?php
break;
}
?>
</article>
<?php endforeach; ?>
<?php if ( $searchwp_query->max_num_pages > 1 ) : ?>
<div class="navigation pagination" role="navigation">
<h2 class="screen-reader-text">Results navigation</h2>
<div class="nav-links"><?php echo wp_kses_post( $search_pagination ); ?></div>
</div>
<?php endif; ?>
<?php elseif ( ! empty( $search_query ) ) : ?>
<p>No results found, please search again.</p>
<?php endif; ?>
</main> <!-- .site-main -->
</div> <!-- .content-area -->
<?php get_footer(); ?>
Now lets style the search results
.entry-thumb-col {
width: 20%;
float: left;
height: 100%;
text-align: center;
}
.entry-content-col {
width: 80%;
float: left;
/*padding: 10px;*/
}
.entry-wrap:after {
content: "";
display: table;
clear: both;
background-color: #fff;
}
.entry-wrap {
margin: 30px;
background-color: #fff;
box-shadow: 0px 0px 10px 0px rgb(0 0 0 / 15%);
transition: background 0.3s, border 0.3s, border-radius 0.3s, box-shadow 0.3s;
padding: 20px;
padding-left: 0;
border-radius: 5px;
}
.entry-thumb-col img {
border-radius: 100px;
}
.entry-title a{
font-size: 24px;
font-weight: bold;
text-align: left;
color: #000;
}
.entry-summary a {
color: #000;
}
.entry-header {
margin-bottom: 1rem;
}
.entry-summary p:last-child {
margin-bottom: 0px;
}
Create your Search Results page and use your new Search Results template
Create a shortcode for your search form. We want the search form action to point to the search page that we created for the search template. (/search-results/)
function SocialHost_display_search_form() {
$search_form = '<form method="get" id="search-form" action="'. esc_url(site_url( '/search-results/' )) .'">
<input type="search" name="searchwp" id="searchwp" placeholder="Search..">
<button type="submit" title="Search" aria-label="Search">
<i aria-hidden="true" class="fas fa-search"></i>
</button>
</form>';
return $search_form;
}
add_shortcode('display_search_form', 'SocialHost_display_search_form');
Add the shortcode to a header [display_search_form]
Style the search form. Here is an example that uses a couple of Elementor global variables
#search-form button {
background-color: var( --e-global-color-primary );
--e-search-form-submit-icon-size: 18px;
margin-left: -5px;
border-radius: 0px 5px 5px 0px !important;
}
#search-form input {
background-color: var( --e-global-color-4e98020 );
margin-right: 0px;
border-radius: 5px 0px 0px 5px !important;
width: 70%;
}
#search-form {
margin-bottom: 0px;
}