/**
  * Create new ES field mappings for the given fields from the configuration
  * TODO align callback names with Config::names so we can simply call this method with the kind string
  * @param array $config_fields
  * @param string $kind of internal fields: meta|field|taxonomy used to call the right indexer_map filter
  */
 static function _map_values($config_fields, $kind)
 {
     $index = self::_index(false);
     $numeric = Config::option('numeric');
     $notanalyzed = Config::option('not_analyzed');
     foreach ($config_fields as $field) {
         // set default
         $props = array('type' => 'string');
         // detect special field type
         if (isset($numeric[$field])) {
             $props['type'] = 'float';
         } elseif (isset($notanalyzed[$field]) || $kind == 'taxonomy') {
             $props['index'] = 'not_analyzed';
         } elseif ($field == 'post_date') {
             $props['type'] = 'date';
             $props['format'] = 'date_time_no_millis';
         } else {
             $props['index'] = 'analyzed';
         }
         if ($props['type'] == 'string' && $props['index'] == 'analyzed') {
             // provides more accurate searches
             // TODO: assumes plugin users are in english
             $lang = Config::apply_filters('string_language', 'english');
             $props = array('type' => 'multi_field', 'fields' => array($field => $props, $lang => array_merge($props, array('analyzer' => $lang))));
         }
         // generic filter indexer_map_field| indexer_map_meta | indexer_map_taxonomy
         $props = Config::apply_filters('indexer_map_' . $kind, $props, $field);
         // also index taxonomy_name field
         if ($kind == 'taxonomy') {
             $tax_name_props = array('type' => 'string');
             $tax_name_props = Config::apply_filters('indexer_map_taxonomy_name', $tax_name_props, $field);
         }
         foreach (Config::types() as $type) {
             $type = $index->getType($type);
             $mapping = new \Elastica\Type\Mapping($type);
             $mapping->setProperties(array($field => $props));
             $mapping->send();
             // second mapping for taxonomy_name
             if (isset($tax_name_props)) {
                 $mapping = new \Elastica\Type\Mapping($type);
                 $mapping->setProperties(array($field . '_name' => $tax_name_props));
                 $mapping->send();
             }
         }
     }
 }
 /**
  * Create new ES field mappings for the given fields from the configuration
  * TODO align callback names with Config::names so we can simply call this method with the kind string
  * @param array $config_fields
  * @param string $kind of internal fields: meta|field|taxonomy used to call the right indexer_map filter
  */
 static function _map_values(&$properties, $type, $config_fields, $kind)
 {
     $index = self::_index(false);
     $numeric = Config::option('numeric');
     $notanalyzed = Config::option('not_analyzed');
     foreach ($config_fields as $field) {
         // set default
         $props = array('type' => 'string');
         // detect special field type
         if (isset($numeric[$field])) {
             $props['type'] = 'float';
         } elseif (isset($notanalyzed[$field]) || $kind == 'taxonomy' || $field == 'post_type') {
             $props['index'] = 'not_analyzed';
         } elseif ($field == 'post_date') {
             $props['type'] = 'date';
             $props['format'] = 'date_time_no_millis';
         } else {
             $props['index'] = 'analyzed';
         }
         if ($props['type'] == 'string' && $props['index'] == 'analyzed') {
             // provides more accurate searches
             $lang = Config::apply_filters('string_language', 'english');
             $props = array('type' => 'multi_field', 'fields' => array($field => $props, $lang => array_merge($props, array('analyzer' => $lang))));
         }
         // generic filter indexer_map_field| indexer_map_meta | indexer_map_taxonomy
         $props = Config::apply_filters('indexer_map_' . $kind, $props, $field);
         // also index taxonomy_name field
         if ($kind == 'taxonomy') {
             $tax_name_props = array('type' => 'string');
             $tax_name_props = Config::apply_filters('indexer_map_taxonomy_name', $tax_name_props, $field);
         }
         $properties[$field] = $props;
         if (isset($tax_name_props)) {
             $properties[$field . '_name'] = $tax_name_props;
         }
     }
 }
			<?php 
        });
    }
});
add_action('init', function () {
    Theme::enableAjaxHooks();
    $args = array();
    $args['share_icons']['twitter'] = array('link' => 'http://twitter.com/parisholley', 'title' => 'Folow me on Twitter', 'img' => NHP_OPTIONS_URL . 'img/glyphicons/glyphicons_322_twitter.png');
    $args['share_icons']['linked_in'] = array('link' => 'http://www.linkedin.com/in/parisholley', 'title' => 'Find me on LinkedIn', 'img' => NHP_OPTIONS_URL . 'img/glyphicons/glyphicons_337_linked_in.png');
    $args['opt_name'] = 'elasticsearch';
    $args['menu_title'] = 'ElasticSearch';
    $args['page_title'] = 'ElasticSearch';
    $args['page_slug'] = 'elastic_search';
    $args['show_import_export'] = false;
    $args['page_position'] = 10241988;
    $args['dev_mode'] = false;
    $args['menu_icon'] = plugins_url('/wp/images/menu.png', __FILE__);
    $args['page_icon'] = 'elasticsearch-icon';
    $sections = array();
    require 'wp/admin/sections/wordpress-integration.php';
    require 'wp/admin/sections/server-settings.php';
    require 'wp/admin/sections/content-indexing.php';
    require 'wp/admin/sections/field-mapping.php';
    require 'wp/admin/sections/results-scoring.php';
    require 'wp/admin/sections/manage-index.php';
    global $NHP_Options;
    $tabs = array();
    $sections = Config::apply_filters("nhp_options_section_setup", $sections);
    $args = Config::apply_filters("nhp_options_args_setup", $args);
    $NHP_Options = new \NHP_Options($sections, $args, $tabs);
}, 10241988);
 /**
  * @internal
  **/
 public static function _buildQuery($search, $facets = array())
 {
     global $blog_id;
     $search = str_ireplace(array(' and ', ' or '), array(' AND ', ' OR '), $search);
     $fields = array();
     $musts = array();
     $filters = array();
     $scored = array();
     foreach (Config::taxonomies() as $tax) {
         if ($search) {
             $score = Config::score('tax', $tax);
             if ($score > 0) {
                 $scored[] = "{$tax}_name^{$score}";
             }
         }
         self::_filterBySelectedFacets($tax, $facets, 'term', $musts, $filters);
     }
     $args = array();
     $numeric = Config::option('numeric');
     $exclude = Config::apply_filters('searcher_query_exclude_fields', array('post_date'));
     $fields = Config::fields();
     self::_searchField($fields, 'field', $exclude, $search, $facets, $musts, $filters, $scored, $numeric);
     self::_searchField(Config::meta_fields(), 'meta', $exclude, $search, $facets, $musts, $filters, $scored, $numeric);
     if (count($scored) > 0 && $search) {
         $qs = array('fields' => $scored, 'query' => $search);
         $fuzzy = Config::option('fuzzy');
         if ($fuzzy && strpos($search, "~") > -1) {
             $qs['fuzzy_min_sim'] = $fuzzy;
         }
         $qs = Config::apply_filters('searcher_query_string', $qs);
         $musts[] = array('query_string' => $qs);
     }
     if (in_array('post_type', $fields)) {
         self::_filterBySelectedFacets('post_type', $facets, 'term', $musts, $filters);
     }
     if (count($filters) > 0) {
         $args['filter']['bool']['should'] = $filters;
     }
     if (count($musts) > 0) {
         $args['query']['bool']['must'] = $musts;
     }
     $args['filter']['bool']['must'][] = array('term' => array('blog_id' => $blog_id));
     $args = Config::apply_filters('searcher_query_pre_facet_filter', $args);
     if (in_array('post_type', $fields)) {
         $args['facets']['post_type']['terms'] = array('field' => 'post_type', 'size' => Config::apply_filters('searcher_query_facet_size', 100));
     }
     // return facets
     foreach (Config::facets() as $facet) {
         $args['facets'][$facet]['terms'] = array('field' => $facet, 'size' => Config::apply_filters('searcher_query_facet_size', 100));
         $args['facets'][$facet]['facet_filter'] = array('bool' => array('must' => array(array('term' => array('blog_id' => $blog_id)))));
         if (count($filters) > 0) {
             $applicable = array();
             foreach ($filters as $filter) {
                 if (isset($filter['term']) && !in_array($facet, array_keys($filter['term']))) {
                     // do not filter on itself when using OR
                     $applicable[] = $filter;
                 }
             }
             if (count($applicable) > 0) {
                 $args['facets'][$facet]['facet_filter']['bool']['should'] = $applicable;
             }
         }
     }
     if (is_array($numeric)) {
         foreach (array_keys($numeric) as $facet) {
             $ranges = Config::ranges($facet);
             if (count($ranges) > 0) {
                 $args['facets'][$facet]['range'][$facet] = array_values($ranges);
                 $args['facets'][$facet]['facet_filter'] = array('bool' => array('must' => array(array('term' => array('blog_id' => $blog_id)))));
             }
         }
     }
     return Config::apply_filters('searcher_query_post_facet_filter', $args);
 }
 public static function _searchField($fields, $type, $exclude, $search, $facets, &$musts, &$filters, &$scored, $numeric)
 {
     foreach ($fields as $field) {
         if (in_array($field, $exclude)) {
             continue;
         }
         if ($search) {
             $score = Config::score($type, $field);
             $notanalyzed = Config::option('not_analyzed');
             if ($score > 0) {
                 if (strpos($search, "~") > -1 || isset($notanalyzed[$field])) {
                     // TODO: fuzzy doesn't work with english analyzer
                     $scored[] = "{$field}^{$score}";
                 } else {
                     $scored[] = sprintf("{$field}.%s^{$score}", Config::apply_filters('string_language', 'english'));
                 }
             }
         }
         if (isset($numeric[$field]) && $numeric[$field]) {
             $ranges = Config::ranges($field);
             if (count($ranges) > 0) {
                 $transformed = array();
                 foreach ($ranges as $key => $range) {
                     $transformed[$key] = array();
                     if (isset($range['to'])) {
                         $transformed[$key]['lt'] = $range['to'];
                     }
                     if (isset($range['from'])) {
                         $transformed[$key]['gte'] = $range['from'];
                     }
                 }
                 self::_filterBySelectedFacets($field, $facets, 'range', $musts, $filters, $transformed);
             }
         } else {
             if ($type == 'custom') {
                 self::_filterBySelectedFacets($field, $facets, 'term', $musts, $filters);
             }
         }
     }
 }
 /**
  * Gather facet information for custom fields that were indexes. Example of output:
  *
  * <code>
  *    array(
  *        'available' => array(
  *            'key1' => array(
  *                'count' => 4,
  *                'value'    => 'value1'
  *            )
  *        ),
  *        'selected' => array(
  *            'key2' => array(
  *                'count' => 6,
  *                'value'    => 'value2'
  *            )
  *        ),
  *        'total' => 10
  *    )
  *    </code>
  *
  * @param string $field Field to lookup in faceting data
  *
  * @return array An associative array based on example provided
  **/
 static function custom($field)
 {
     global $wp_query;
     $data = isset($wp_query->facets[$field]) ? $wp_query->facets[$field] : array();
     return self::_buildFacetResult($field, $data, function ($value) use($field, $data) {
         $return = array('slug' => $value);
         return Config::apply_filters('faceting_custom', $return, $field, $data);
     });
 }