/** * Takes SQL query part, and translates it into an ES filter * * @param $query * * @return array ES filter */ protected function get_es_filter_for_clause($query) { // The sub-parts of a $where part. $filter_parts = array(); $column = !empty($query['column']) ? $query['column'] : $this->column; $compare = $this->get_compare($query); $inclusive = !empty($query['inclusive']) && $query['inclusive'] === true ? true : false; // Assign greater- and less-than values. $lt = 'lt'; $gt = 'gt'; if ($inclusive) { $lt .= 'e'; $gt .= 'e'; } // Range queries. if (!empty($query['after'])) { $range_filters = array("{$column}" => array("{$gt}" => $this->build_mysql_datetime($query['after']))); } if (!empty($query['before'])) { $range_filters = empty($range_filters[$column]) ? array("{$column}" => array("{$lt}" => array())) : $range_filters; $range_filters[$column][$lt] = $this->build_mysql_datetime($query['before']); } if (!empty($query['after']) || !empty($query['before'])) { $filter_parts['range_filters'] = $range_filters; } // Specific value queries. $date_parameters = array('year' => !empty($query['year']) ? $query['year'] : false, 'month' => !empty($query['month']) ? $query['month'] : false, 'week' => !empty($query['week']) ? $query['week'] : false, 'dayofyear' => !empty($query['dayofyear']) ? $query['dayofyear'] : false, 'day' => !empty($query['day']) ? $query['day'] : false, 'dayofweek' => !empty($query['dayofweek']) ? $query['dayofweek'] : false, 'dayofweek_iso' => !empty($query['dayofweek_iso']) ? $query['dayofweek_iso'] : false, 'hour' => !empty($query['hour']) ? $query['hour'] : false, 'minute' => !empty($query['minute']) ? $query['minute'] : false, 'second' => !empty($query['second']) ? $query['second'] : false, 'm' => !empty($query['m']) ? $query['m'] : false); if (empty($date_parameters['month']) && !empty($query['monthnum'])) { $date_parameters['month'] = $query['monthnum']; } if (empty($date_parameters['week']) && !empty($query['w'])) { $date_parameters['week'] = $query['w']; } foreach ($date_parameters as $param => $value) { if (false === $value) { unset($date_parameters[$param]); } } if ($date_parameters) { EP_WP_Date_Query::validate_date_values($date_parameters); $date_terms = array('must' => array(), 'should' => array(), 'must_not' => array()); foreach ($date_parameters as $param => $value) { if ('=' === $compare) { $date_terms['must'][]['term']["date_terms.{$param}"] = $value; } else { if ('!=' === $compare) { $date_terms['must_not'][]['term']["date_terms.{$param}"] = $value; } else { if ('IN' === $compare) { foreach ($value as $in_value) { $date_terms['should'][]['term']["date_terms.{$param}"] = $in_value; } } else { if ('NOT IN' === $compare) { foreach ($value as $in_value) { $date_terms['must_not'][]['term']["date_terms.{$param}"] = $in_value; } } else { if ('BETWEEN' === $compare) { $range_filter["date_terms.{$param}"] = array(); $range_filter["date_terms.{$param}"]['gte'] = $value[0]; $range_filter["date_terms.{$param}"]['lte'] = $value[1]; $filter_parts['range_filters'] = $range_filter; } else { if ('NOT BETWEEN' === $compare) { $range_filter["date_terms.{$param}"] = array(); $range_filter["date_terms.{$param}"]['gt'] = $value[0]; $range_filter["date_terms.{$param}"]['lt'] = $value[1]; $filter_parts['range_filters'] = array('not' => $range_filter); } else { if (strpos($compare, '>') !== false) { $range = strpos($compare, '=') !== false ? 'gte' : 'gt'; $range_filter["date_terms.{$param}"] = array(); $range_filter["date_terms.{$param}"][$range] = $value; $filter_parts['range_filters'] = $range_filter; } else { if (strpos($compare, '<') !== false) { $range = strpos($compare, '=') !== false ? 'lte' : 'lt'; $range_filter["date_terms.{$param}"] = array(); $range_filter["date_terms.{$param}"][$range] = $value; $filter_parts['range_filters'] = $range_filter; } } } } } } } } } $date_terms = array_filter($date_terms); if (!empty($date_terms)) { $filter_parts['date_terms'] = $date_terms; } } return $filter_parts; }
/** * Format WP query args for ES * * @param array $args * @since 0.9.0 * @return array */ public function format_args($args) { if (!empty($args['post_per_page'])) { $posts_per_page = $args['post_per_page']; } else { $posts_per_page = get_option('posts_per_page'); } $formatted_args = array('from' => 0, 'size' => $posts_per_page); /** * Order and Orderby arguments * * Used for how Elasticsearch will sort results * * @since 1.1 */ // Set sort order, default is 'desc' if (!empty($args['order'])) { $order = $this->parse_order($args['order']); } else { $order = 'desc'; } // Set sort type if (!empty($args['orderby'])) { $sort = $this->parse_orderby($args['orderby'], $order); if (false !== $sort) { $formatted_args['sort'] = $sort; } } // Either nothing was passed or the parse_orderby failed, use default sort if (empty($args['orderby']) || false === $sort) { // Default sort is to use the score (based on relevance) $default_sort = array(array('_score' => array('order' => $order))); $default_sort = apply_filters('ep_set_default_sort', $default_sort, $order); $formatted_args['sort'] = $default_sort; } $filter = array('and' => array()); $use_filters = false; /** * Tax Query support * * Support for the tax_query argument of WP_Query * Currently only provides support for the 'AND' relation between taxonomies * * @use field = slug * terms array * @since 0.9.1 */ if (!empty($args['tax_query'])) { $tax_filter = array(); foreach ($args['tax_query'] as $single_tax_query) { if (!empty($single_tax_query['terms']) && !empty($single_tax_query['field']) && 'slug' === $single_tax_query['field']) { $terms = (array) $single_tax_query['terms']; // Set up our terms object $terms_obj = array('terms.' . $single_tax_query['taxonomy'] . '.slug' => $terms); // Use the AND operator if passed if (!empty($single_tax_query['operator']) && 'AND' === $single_tax_query['operator']) { $terms_obj['execution'] = 'and'; } // Add the tax query filter $tax_filter[]['terms'] = $terms_obj; } } if (!empty($tax_filter)) { $filter['and'][]['bool']['must'] = $tax_filter; } $use_filters = true; } /** * 'category_name' arg support. * * @since 1.5 */ if (!empty($args['category_name'])) { $terms_obj = array('terms.category.slug' => array($args['category_name'])); $filter['and'][]['bool']['must'] = array('terms' => $terms_obj); $use_filters = true; } /** * Author query support * * @since 1.0 */ if (!empty($args['author'])) { $filter['and'][] = array('term' => array('post_author.id' => $args['author'])); $use_filters = true; } elseif (!empty($args['author_name'])) { $filter['and'][] = array('term' => array('post_author.raw' => $args['author'])); $use_filters = true; } /** * Simple date params support * * @since 1.3 */ if ($date_filter = EP_WP_Date_Query::simple_es_date_filter($args)) { $filter['and'][] = $date_filter; $use_filters = true; } /** * 'date_query' arg support. * */ if (!empty($args['date_query'])) { $date_query = new EP_WP_Date_Query($args['date_query']); $date_filter = $date_query->get_es_filter(); if (array_key_exists('and', $date_filter)) { $filter['and'][] = $date_filter['and']; $use_filters = true; } } /** * 'meta_query' arg support. * * Relation supports 'AND' and 'OR'. 'AND' is the default. For each individual query, the * following 'compare' values are supported: =, !=, EXISTS, NOT EXISTS. '=' is the default. * 'type' is NOT support at this time. * * @since 1.3 */ if (!empty($args['meta_query'])) { $meta_filter = array(); $relation = 'must'; if (!empty($args['meta_query']['relation']) && 'or' === strtolower($args['meta_query']['relation'])) { $relation = 'should'; } foreach ($args['meta_query'] as $single_meta_query) { if (!empty($single_meta_query['key'])) { $terms_obj = false; $compare = '='; if (!empty($single_meta_query['compare'])) { $compare = strtolower($single_meta_query['compare']); } switch ($compare) { case '!=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must_not' => array(array('terms' => array('post_meta.' . $single_meta_query['key'] . '.raw' => (array) $single_meta_query['value']))))); } break; case 'exists': $terms_obj = array('exists' => array('field' => 'post_meta.' . $single_meta_query['key'])); break; case 'not exists': $terms_obj = array('bool' => array('must_not' => array(array('exists' => array('field' => 'post_meta.' . $single_meta_query['key']))))); break; case '>=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array('post_meta.' . $single_meta_query['key'] . '.raw' => array("gte" => $single_meta_query['value'])))))); } break; case '<=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array('post_meta.' . $single_meta_query['key'] . '.raw' => array("lte" => $single_meta_query['value'])))))); } break; case '>': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array('post_meta.' . $single_meta_query['key'] . '.raw' => array("gt" => $single_meta_query['value'])))))); } break; case '<': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array('post_meta.' . $single_meta_query['key'] . '.raw' => array("lt" => $single_meta_query['value'])))))); } break; case 'like': if (isset($single_meta_query['value'])) { $terms_obj = array('query' => array("match" => array('post_meta.' . $single_meta_query['key'] => $single_meta_query['value']))); } break; case '=': default: if (isset($single_meta_query['value'])) { $terms_obj = array('terms' => array('post_meta.' . $single_meta_query['key'] . '.raw' => (array) $single_meta_query['value'])); } break; } // Add the meta query filter if (false !== $terms_obj) { $meta_filter[] = $terms_obj; } } } if (!empty($meta_filter)) { $filter['and'][]['bool'][$relation] = $meta_filter; $use_filters = true; } } /** * Allow for search field specification * * @since 1.0 */ if (!empty($args['search_fields'])) { $search_field_args = $args['search_fields']; $search_fields = array(); if (!empty($search_field_args['taxonomies'])) { $taxes = (array) $search_field_args['taxonomies']; foreach ($taxes as $tax) { $search_fields[] = 'terms.' . $tax . '.name'; } unset($search_field_args['taxonomies']); } if (!empty($search_field_args['meta'])) { $metas = (array) $search_field_args['meta']; foreach ($metas as $meta) { $search_fields[] = 'post_meta.' . $meta; } unset($search_field_args['meta']); } if (in_array('author_name', $search_field_args)) { $search_fields[] = 'post_author.login'; unset($search_field_args['author_name']); } $search_fields = array_merge($search_field_args, $search_fields); } else { $search_fields = array('post_title', 'post_excerpt', 'post_content'); } $search_fields = apply_filters('ep_search_fields', $search_fields, $args); $query = array('bool' => array('should' => array(array('multi_match' => array('query' => '', 'fields' => $search_fields, 'boost' => apply_filters('ep_match_boost', 2))), array('fuzzy_like_this' => array('fields' => $search_fields, 'like_text' => '', 'min_similarity' => apply_filters('ep_min_similarity', 0.75)))))); /** * We are using ep_integrate instead of ep_match_all. ep_match_all will be * supported for legacy code but may be deprecated and removed eventually. * * @since 1.3 */ if (!empty($args['s']) && empty($args['ep_match_all']) && empty($args['ep_integrate'])) { $query['bool']['should'][1]['fuzzy_like_this']['like_text'] = $args['s']; $query['bool']['should'][0]['multi_match']['query'] = $args['s']; $formatted_args['query'] = $query; } else { if (!empty($args['ep_match_all']) || !empty($args['ep_integrate'])) { $formatted_args['query']['match_all'] = array(); } } /** * Like WP_Query in search context, if no post_type is specified we default to "any". To * be safe you should ALWAYS specify the post_type parameter UNLIKE with WP_Query. * * @since 1.3 */ if (!empty($args['post_type'])) { // should NEVER be "any" but just in case if ('any' !== $args['post_type']) { $post_types = (array) $args['post_type']; $terms_map_name = 'terms'; if (count($post_types) < 2) { $terms_map_name = 'term'; } $filter['and'][] = array($terms_map_name => array('post_type.raw' => $post_types)); $use_filters = true; } } if (isset($args['offset'])) { $formatted_args['from'] = $args['offset']; } if (isset($args['posts_per_page'])) { $formatted_args['size'] = $args['posts_per_page']; } if (isset($args['paged'])) { $paged = $args['paged'] <= 1 ? 0 : $args['paged'] - 1; $formatted_args['from'] = $args['posts_per_page'] * $paged; } if ($use_filters) { $formatted_args['filter'] = $filter; } /** * Aggregations */ if (isset($args['aggs']) && !empty($args['aggs']['aggs'])) { $agg_obj = $args['aggs']; // Add a name to the aggregation if it was passed through if (!empty($agg_obj['name'])) { $agg_name = $agg_obj['name']; } else { $agg_name = 'aggregation_name'; } // Add/use the filter if warranted if (isset($agg_obj['use-filter']) && false !== $agg_obj['use-filter'] && $use_filters) { // If a filter is being used, use it on the aggregation as well to receive relevant information to the query $formatted_args['aggs'][$agg_name]['filter'] = $filter; $formatted_args['aggs'][$agg_name]['aggs'] = $agg_obj['aggs']; } else { $formatted_args['aggs'][$agg_name] = $args['aggs']; } } return apply_filters('ep_formatted_args', $formatted_args, $args); }
/** * Format WP query args for ES * * @param array $args * @since 0.9.0 * @return array */ public function format_args($args) { if (isset($args['post_per_page'])) { // For backwards compatibility for those using this since EP 1.4 $args['posts_per_page'] = $args['post_per_page']; } if (!empty($args['posts_per_page'])) { $posts_per_page = (int) $args['posts_per_page']; if (-1 === $posts_per_page) { $posts_per_page = 10000; // -1 does not work, use max result window for ES } } else { $posts_per_page = (int) get_option('posts_per_page'); } $formatted_args = array('from' => 0, 'size' => $posts_per_page); /** * Order and Orderby arguments * * Used for how Elasticsearch will sort results * * @since 1.1 */ // Set sort order, default is 'desc' if (!empty($args['order'])) { $order = $this->parse_order($args['order']); } else { $order = 'desc'; } // Default sort for non-searches to date if (empty($args['orderby']) && (!isset($args['s']) || '' === $args['s'])) { $args['orderby'] = 'date'; } // Set sort type if (!empty($args['orderby'])) { $formatted_args['sort'] = $this->parse_orderby($args['orderby'], $order, $args); } else { // Default sort is to use the score (based on relevance) $default_sort = array(array('_score' => array('order' => $order))); $default_sort = apply_filters('ep_set_default_sort', $default_sort, $order); $formatted_args['sort'] = $default_sort; } $filter = array('bool' => array('must' => array())); $use_filters = false; /** * Tax Query support * * Support for the tax_query argument of WP_Query. Currently only provides support for the 'AND' relation * between taxonomies. Field only supports slug, term_id, and name defaulting to term_id. * * @use field = slug * terms array * @since 0.9.1 */ //set tax_query if it's implicitly set in the query //e.g. $args['tag'], $args['category_name'] if (empty($args['tax_query'])) { $taxonomies = get_taxonomies(); $taxonomies = $this->sanitize_taxonomy_names($taxonomies); //fix it up foreach ($taxonomies as $tax => $taxName) { if (isset($args[$taxName]) && !empty($args[$taxName])) { $args['tax_query'][] = array('taxonomy' => $tax, 'terms' => array($args[$taxName]), 'field' => 'slug'); } } } if (!empty($args['tax_query'])) { $tax_filter = array(); foreach ($args['tax_query'] as $single_tax_query) { if (!empty($single_tax_query['terms'])) { $terms = (array) $single_tax_query['terms']; $field = !empty($single_tax_query['field']) ? $single_tax_query['field'] : 'term_id'; if ('name' === $field) { $field = 'name.raw'; } // Set up our terms object $terms_obj = array('terms.' . $single_tax_query['taxonomy'] . '.' . $field => $terms); // Use the AND operator if passed if (!empty($single_tax_query['operator']) && 'AND' === $single_tax_query['operator']) { $terms_obj['execution'] = 'and'; } // Add the tax query filter $tax_filter[]['terms'] = $terms_obj; } } if (!empty($tax_filter)) { $relation = 'must'; if (!empty($args['tax_query']['relation']) && 'or' === strtolower($args['tax_query']['relation'])) { $relation = 'should'; } $filter['bool']['must'][]['bool'][$relation] = $tax_filter; } $use_filters = true; } /** * 'post_parent' arg support. * * @since 2.0 */ if (isset($args['post_parent']) && '' !== $args['post_parent'] && 'any' !== strtolower($args['post_parent'])) { $filter['bool']['must'][]['bool']['must'] = array('term' => array('post_parent' => $args['post_parent'])); $use_filters = true; } /** * 'post__in' arg support. * * @since x.x */ if (!empty($args['post__in'])) { $filter['bool']['must'][]['bool']['must'] = array('terms' => array('post_id' => array_values((array) $args['post__in']))); $use_filters = true; } /** * 'post__not_in' arg support. * * @since x.x */ if (!empty($args['post__not_in'])) { $filter['bool']['must'][]['bool']['must_not'] = array('terms' => array('post_id' => (array) $args['post__not_in'])); $use_filters = true; } /** * Author query support * * @since 1.0 */ if (!empty($args['author'])) { $filter['bool']['must'][] = array('term' => array('post_author.id' => $args['author'])); $use_filters = true; } elseif (!empty($args['author_name'])) { $filter['bool']['must'][] = array('term' => array('post_author.raw' => $args['author'])); $use_filters = true; } /** * Simple date params support * * @since 1.3 */ if ($date_filter = EP_WP_Date_Query::simple_es_date_filter($args)) { $filter['bool']['must'][] = $date_filter; $use_filters = true; } /** * 'date_query' arg support. * */ if (!empty($args['date_query'])) { $date_query = new EP_WP_Date_Query($args['date_query']); $date_filter = $date_query->get_es_filter(); if (array_key_exists('and', $date_filter)) { $filter['bool']['must'][] = $date_filter['and']; $use_filters = true; } } $meta_queries = array(); /** * Support meta_key * * @since 2.1 */ if (!empty($args['meta_key'])) { if (!empty($args['meta_value'])) { $meta_value = $args['meta_value']; } elseif (!empty($args['meta_value_num'])) { $meta_value = $args['meta_value_num']; } if (!empty($meta_value)) { $meta_queries[] = array('key' => $args['meta_key'], 'value' => $meta_value); } } /** * Todo: Support meta_type */ /** * 'meta_query' arg support. * * Relation supports 'AND' and 'OR'. 'AND' is the default. For each individual query, the * following 'compare' values are supported: =, !=, EXISTS, NOT EXISTS. '=' is the default. * * @since 1.3 */ if (!empty($args['meta_query'])) { $meta_queries = array_merge($meta_queries, $args['meta_query']); } if (!empty($meta_queries)) { $meta_filter = array(); $relation = 'must'; if (!empty($args['meta_query']) && !empty($args['meta_query']['relation']) && 'or' === strtolower($args['meta_query']['relation'])) { $relation = 'should'; } $meta_query_type_mapping = array('numeric' => 'long', 'binary' => 'raw', 'char' => 'raw', 'date' => 'date', 'datetime' => 'datetime', 'decimal' => 'double', 'signed' => 'long', 'time' => 'time', 'unsigned' => 'long'); foreach ($meta_queries as $single_meta_query) { /** * There is a strange case where meta_query looks like this: * array( * "something" => array( * array( * 'key' => ... * ... * ) * ) * ) * * Somehow WordPress (WooCommerce) handles that case so we need to as well. * * @since 2.1 */ if (is_array($single_meta_query) && empty($single_meta_query['key'])) { reset($single_meta_query); $first_key = key($single_meta_query); if (is_array($single_meta_query[$first_key])) { $single_meta_query = $single_meta_query[$first_key]; } } if (!empty($single_meta_query['key'])) { $terms_obj = false; $compare = '='; if (!empty($single_meta_query['compare'])) { $compare = strtolower($single_meta_query['compare']); } $type = null; if (!empty($single_meta_query['type'])) { $type = strtolower($single_meta_query['type']); } // Comparisons need to look at different paths if (in_array($compare, array('exists', 'not exists'))) { $meta_key_path = 'meta.' . $single_meta_query['key']; } elseif (in_array($compare, array('=', '!=')) && !$type) { $meta_key_path = 'meta.' . $single_meta_query['key'] . '.raw'; } elseif ('like' === $compare) { $meta_key_path = 'meta.' . $single_meta_query['key'] . '.value'; } elseif ($type && isset($meta_query_type_mapping[$type])) { // Map specific meta field types to different Elasticsearch core types $meta_key_path = 'meta.' . $single_meta_query['key'] . '.' . $meta_query_type_mapping[$type]; } elseif (in_array($compare, array('>=', '<=', '>', '<', 'between'))) { $meta_key_path = 'meta.' . $single_meta_query['key'] . '.double'; } else { $meta_key_path = 'meta.' . $single_meta_query['key'] . '.raw'; } switch ($compare) { case 'not in': case '!=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must_not' => array(array('terms' => array($meta_key_path => (array) $single_meta_query['value']))))); } break; case 'exists': $terms_obj = array('exists' => array('field' => $meta_key_path)); break; case 'not exists': $terms_obj = array('bool' => array('must_not' => array(array('exists' => array('field' => $meta_key_path))))); break; case '>=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array($meta_key_path => array("gte" => $single_meta_query['value'])))))); } break; case 'between': if (isset($single_meta_query['value']) && is_array($single_meta_query['value']) && 2 === count($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array($meta_key_path => array("gte" => $single_meta_query['value'][0]))), array('range' => array($meta_key_path => array("lte" => $single_meta_query['value'][1])))))); } break; case '<=': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array($meta_key_path => array('lte' => $single_meta_query['value'])))))); } break; case '>': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array($meta_key_path => array('gt' => $single_meta_query['value'])))))); } break; case '<': if (isset($single_meta_query['value'])) { $terms_obj = array('bool' => array('must' => array(array('range' => array($meta_key_path => array('lt' => $single_meta_query['value'])))))); } break; case 'like': if (isset($single_meta_query['value'])) { $terms_obj = array('query' => array('match' => array($meta_key_path => $single_meta_query['value']))); } break; case '=': default: if (isset($single_meta_query['value'])) { $terms_obj = array('terms' => array($meta_key_path => (array) $single_meta_query['value'])); } break; } // Add the meta query filter if (false !== $terms_obj) { $meta_filter[] = $terms_obj; } } } if (!empty($meta_filter)) { $filter['bool']['must'][]['bool'][$relation] = $meta_filter; $use_filters = true; } } /** * Allow for search field specification * * @since 1.0 */ if (!empty($args['search_fields'])) { $search_field_args = $args['search_fields']; $search_fields = array(); if (!empty($search_field_args['taxonomies'])) { $taxes = (array) $search_field_args['taxonomies']; foreach ($taxes as $tax) { $search_fields[] = 'terms.' . $tax . '.name'; } unset($search_field_args['taxonomies']); } if (!empty($search_field_args['meta'])) { $metas = (array) $search_field_args['meta']; foreach ($metas as $meta) { $search_fields[] = 'meta.' . $meta . '.value'; } unset($search_field_args['meta']); } if (in_array('author_name', $search_field_args)) { $search_fields[] = 'post_author.login'; unset($search_field_args['author_name']); } $search_fields = array_merge($search_field_args, $search_fields); } else { $search_fields = array('post_title', 'post_excerpt', 'post_content'); } $search_fields = apply_filters('ep_search_fields', $search_fields, $args); $query = array('bool' => array('should' => array(array('multi_match' => array('query' => '', 'type' => 'phrase', 'fields' => $search_fields, 'boost' => apply_filters('ep_match_phrase_boost', 4, $search_fields, $args))), array('multi_match' => array('query' => '', 'fields' => $search_fields, 'boost' => apply_filters('ep_match_boost', 2, $search_fields, $args), 'fuzziness' => 0, 'operator' => 'and')), array('multi_match' => array('fields' => $search_fields, 'query' => '', 'fuzziness' => apply_filters('ep_fuzziness_arg', 1, $search_fields, $args)))))); /** * We are using ep_integrate instead of ep_match_all. ep_match_all will be * supported for legacy code but may be deprecated and removed eventually. * * @since 1.3 */ if (!empty($args['s']) && empty($args['ep_match_all']) && empty($args['ep_integrate'])) { $query['bool']['should'][2]['multi_match']['query'] = $args['s']; $query['bool']['should'][1]['multi_match']['query'] = $args['s']; $query['bool']['should'][0]['multi_match']['query'] = $args['s']; $formatted_args['query'] = $query; } else { if (!empty($args['ep_match_all']) || !empty($args['ep_integrate'])) { $formatted_args['query']['match_all'] = array('boost' => 1); } } /** * If not set default to post. If search and not set, default to "any". */ if (!empty($args['post_type'])) { // should NEVER be "any" but just in case if ('any' !== $args['post_type']) { $post_types = (array) $args['post_type']; $terms_map_name = 'terms'; if (count($post_types) < 2) { $terms_map_name = 'term'; $post_types = $post_types[0]; } $filter['bool']['must'][] = array($terms_map_name => array('post_type.raw' => $post_types)); $use_filters = true; } } elseif (empty($args['s'])) { $filter['bool']['must'][] = array('term' => array('post_type.raw' => 'post')); $use_filters = true; } /** * Like WP_Query in search context, if no post_status is specified we default to "any". To * be safe you should ALWAYS specify the post_status parameter UNLIKE with WP_Query. * * @since 2.1 */ if (!empty($args['post_status'])) { // should NEVER be "any" but just in case if ('any' !== $args['post_status']) { $post_status = (array) $args['post_status']; $terms_map_name = 'terms'; if (count($post_status) < 2) { $terms_map_name = 'term'; $post_status = $post_status[0]; } $filter['bool']['must'][] = array($terms_map_name => array('post_status' => $post_status)); $use_filters = true; } } else { $filter['bool']['must'][] = array('term' => array('post_status' => 'publish')); $use_filters = true; } if (isset($args['offset'])) { $formatted_args['from'] = $args['offset']; } if (isset($args['paged']) && $args['paged'] > 1) { $formatted_args['from'] = $args['posts_per_page'] * ($args['paged'] - 1); } if ($use_filters) { $formatted_args['post_filter'] = $filter; } /** * Aggregations */ if (isset($args['aggs']) && !empty($args['aggs']['aggs'])) { $agg_obj = $args['aggs']; // Add a name to the aggregation if it was passed through if (!empty($agg_obj['name'])) { $agg_name = $agg_obj['name']; } else { $agg_name = 'aggregation_name'; } // Add/use the filter if warranted if (isset($agg_obj['use-filter']) && false !== $agg_obj['use-filter'] && $use_filters) { // If a filter is being used, use it on the aggregation as well to receive relevant information to the query $formatted_args['aggs'][$agg_name]['filter'] = $filter; $formatted_args['aggs'][$agg_name]['aggs'] = $agg_obj['aggs']; } else { $formatted_args['aggs'][$agg_name] = $args['aggs']; } } return apply_filters('ep_formatted_args', $formatted_args, $args); }