<?php
/**
* Jet_Search_Ajax_Handlers class
*
* @package jet-search
* @author Zemez
* @license GPL-2.0+
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( ! class_exists( 'Jet_Search_Ajax_Handlers' ) ) {
/**
* Define Jet_Search_Ajax_Handlers class
*/
class Jet_Search_Ajax_Handlers {
/**
* A reference to an instance of this class.
*
* @since 1.0.0
* @var Jet_Search_Ajax_Handlers
*/
private static $instance = null;
/**
* Ajax action.
*
* @var string
*/
private $action = 'jet_ajax_search';
/**
* Has navigation.
*
* @var bool
*/
public $has_navigation = false;
/**
* Search query.
*
* @var array
*/
public $search_query = array();
/**
* Table alias.
*
* @var string
*/
private $postmeta_table_alias = 'jetsearch';
/**
* Is the search result page.
*
* @var bool
*/
private $is_search = false;
/**
* Constructor for the class
*/
public function init() {
// Set search query settings on the search result page
add_action( 'pre_get_posts', array( $this, 'set_search_query' ) );
// Search in custom fields
add_filter( 'posts_join', array( $this, 'cf_search_join' ) );
add_filter( 'posts_where', array( $this, 'cf_search_where' ) );
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
add_action( "wp_ajax_{$this->action}", array( $this, 'get_search_results' ) );
add_action( "wp_ajax_nopriv_{$this->action}", array( $this, 'get_search_results' ) );
add_action( 'wp_ajax_jet_search_get_query_control_options', array( $this, 'get_query_control_options' ) );
}
// Init session on search result page
if ( is_search() && ! session_id() ) {
session_start();
}
}
/**
* Get ajax action.
*
* @since 1.1.2
* @return string
*/
public function get_ajax_action() {
return $this->action;
}
/**
* Set search query settings on the search result page.
*
* @param object $query
*/
public function set_search_query( $query ) {
if ( $query->is_search ) {
$this->reset_session_data();
$this->is_search = true;
$form_settings = $this->get_form_settings();
if ( ! empty( $form_settings ) ) {
$this->set_query_settings( $form_settings );
if ( isset( $query->query_vars['jet_smart_filters'] ) ) {
$query->query_vars = array_merge( $this->search_query, $query->query_vars );
} else {
$query->query_vars = array_merge( $query->query_vars, $this->search_query );
}
}
}
}
/**
* Get form settings on the search result page.
*
* @return array
*/
public function get_form_settings() {
$form_settings = array();
if ( ! empty( $_GET['jet_ajax_search_settings'] ) ) {
$form_settings = stripcslashes( $_GET['jet_ajax_search_settings'] );;
$_SESSION['jet_ajax_search_settings'] = $form_settings;
} elseif ( ! empty( $_SESSION['jet_ajax_search_settings'] ) ) {
$form_settings = $_SESSION['jet_ajax_search_settings'];
}
if ( ! empty( $form_settings ) ) {
$form_settings = json_decode( $form_settings );
$form_settings = get_object_vars( $form_settings );
}
return $form_settings;
}
/**
* Reset session data.
*/
public function reset_session_data() {
if ( wp_doing_ajax() || ! isset( $_SESSION['jet_ajax_search_settings'] ) ) {
return;
}
unset( $_SESSION['jet_ajax_search_settings'] );
}
/**
* Get search results.
*/
public function get_search_results() {
//if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'], $this->action ) ) {
// wp_send_json_error( array(
// 'message' => 'Invalid Nonce!'
// ) );
// return;
//}
$data = $this->get_search_data();
if ( empty( $data ) ) {
wp_send_json_error( array(
'message' => 'Empty Search Data'
) );
return;
}
wp_send_json_success( $data );
}
/**
* Get search data.
*
* @return array|bool
*/
public function get_search_data() {
if ( empty( $_GET['data'] ) ) {
return false;
}
$data = $_GET['data'];
$this->search_query['s'] = urldecode( $data['value'] );
$this->search_query['nopaging'] = false;
$this->search_query['ignore_sticky_posts'] = false;
$this->search_query['posts_per_page'] = ( int ) $data['limit_query_in_result_area'];
$this->search_query['post_status'] = 'publish';
$this->set_query_settings( $data );
add_filter( 'wp_query_search_exclusion_prefix', '__return_empty_string' );
$search = new WP_Query( $this->search_query );
$response = array(
'error' => false,
'post_count' => 0,
'message' => '',
'posts' => null,
);
remove_filter( 'wp_query_search_exclusion_prefix', '__return_empty_string' );
if ( is_wp_error( $search ) ) {
$response['error'] = true;
$response['message'] = esc_html( $data['server_error'] );
return $response;
}
if ( empty( $search->post_count ) ) {
$response['message'] = esc_html( $data['negative_search'] );
return $response;
}
$data['limit_query'] = $this->extract_limit_query( $data );
$data['post_count'] = $search->post_count;
$data['columns'] = ceil( $data['post_count'] / $data['limit_query'] );
$response['posts'] = array();
$response['columns'] = $data['columns'];
$response['limit_query'] = $data['limit_query'];
$response['post_count'] = $data['post_count'];
$response['results_navigation'] = $this->get_results_navigation( $data );
foreach ( $search->posts as $key => $post ) {
$response['posts'][ $key ] = array(
'title' => $post->post_title,
'before_title' => Jet_Search_Template_Functions::get_meta_fields( $data, $post, 'title_related', 'jet-search-title-fields', array( 'before' ) ),
'after_title' => Jet_Search_Template_Functions::get_meta_fields( $data, $post, 'title_related', 'jet-search-title-fields', array( 'after' ) ),
'content' => Jet_Search_Template_Functions::get_post_content( $data, $post ),
'before_content' => Jet_Search_Template_Functions::get_meta_fields( $data, $post, 'content_related', 'jet-search-content-fields', array( 'before' ) ),
'after_content' => Jet_Search_Template_Functions::get_meta_fields( $data, $post, 'content_related', 'jet-search-content-fields', array( 'after' ) ),
'thumbnail' => Jet_Search_Template_Functions::get_post_thumbnail( $data, $post ),
'link' => esc_url( get_permalink( $post->ID ) ),
'price' => Jet_Search_Template_Functions::get_product_price( $data, $post ),
'rating' => Jet_Search_Template_Functions::get_product_rating( $data, $post ),
);
$custom_post_data = apply_filters( 'jet-search/ajax-search/custom-post-data', array(), $data, $post );
if ( ! empty( $custom_post_data ) ) {
$response['posts'][ $key ] = array_merge( $response['posts'][ $key ], $custom_post_data );
}
if ( ! $this->has_navigation && $key === $data['limit_query'] - 1 ) {
break;
}
}
return $response;
}
/**
* Set search query settings.
*
* @param array $args
*/
protected function set_query_settings( $args = array() ) {
if ( $args ) {
$this->search_query['cache_results'] = true;
$this->search_query['post_type'] = $args['search_source'];
$this->search_query['order'] = $args['results_order'];
$this->search_query['orderby'] = $args['results_order_by'];
$this->search_query['tax_query'] = array( 'relation' => 'AND' );
$this->search_query['sentence'] = isset( $args['sentence'] ) ? filter_var( $args['sentence'], FILTER_VALIDATE_BOOLEAN ) : false;
$this->search_query['post_status'] = 'publish';
// Include specific terms
if ( ! empty( $args['category__in'] ) ) {
$tax = ! empty( $args['search_taxonomy'] ) ? $args['search_taxonomy'] : 'category';
array_push(
$this->search_query['tax_query'],
array(
'taxonomy' => $tax,
'field' => 'id',
'operator' => 'IN',
'terms' => $args['category__in'],
)
);
} else if ( ! empty( $args['include_terms_ids'] ) ) {
$include_tax_query = array( 'relation' => 'OR' );
$terms_data = $this->prepare_terms_data( $args['include_terms_ids'] );
foreach ( $terms_data as $taxonomy => $terms_ids ) {
$include_tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'id',
'operator' => 'IN',
'terms' => $terms_ids,
);
}
array_push(
$this->search_query['tax_query'],
$include_tax_query
);
}
// Exclude specific terms
if ( ! empty( $args['exclude_terms_ids'] ) ) {
$exclude_tax_query = array( 'relation' => 'OR' );
$terms_data = $this->prepare_terms_data( $args['exclude_terms_ids'] );
foreach ( $terms_data as $taxonomy => $terms_ids ) {
$exclude_tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'id',
'operator' => 'NOT IN',
'terms' => $terms_ids,
);
}
array_push(
$this->search_query['tax_query'],
$exclude_tax_query
);
}
// Exclude specific posts
if ( ! empty( $args['exclude_posts_ids'] ) ) {
$this->search_query['post__not_in'] = $args['exclude_posts_ids'];
}
// Current Query
if ( ! empty( $args['current_query'] ) ) {
$this->search_query = array_merge( $this->search_query, (array) $args['current_query'] );
}
Loading ...