''); $options['facet_field'] = ''; $options['hide_block'] = FALSE; return $options; } public function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); if (substr($this->view->base_table, 0, 17) != 'search_api_index_') { return; } switch ($form_state['section']) { case 'linked_path': $form['#title'] .= t('Search page path'); $form['linked_path'] = array( '#type' => 'textfield', '#description' => t('The menu path to which search facets will link. Leave empty to use the current path.'), '#default_value' => $this->get_option('linked_path'), ); break; case 'facet_field': $form['facet_field'] = array( '#type' => 'select', '#title' => t('Facet field'), '#options' => $this->getFieldOptions(), '#default_value' => $this->get_option('facet_field'), ); break; case 'use_more': $form['use_more']['#description'] = t('This will add a more link to the bottom of this view, which will link to the base path for the facet links.'); $form['use_more_always'] = array( '#type' => 'value', '#value' => $this->get_option('use_more_always'), ); break; case 'hide_block': $form['hide_block'] = array( '#type' => 'checkbox', '#title' => t('Hide block'), '#description' => t('Hide this block, but still execute the search. ' . 'Can be used to show native Facet API facet blocks linking to the search page specified above.'), '#default_value' => $this->get_option('hide_block'), ); break; } } public function options_validate(&$form, &$form_state) { if (substr($this->view->base_table, 0, 17) != 'search_api_index_') { form_set_error('', t('The "Facets block" display can only be used with base tables based on Search API indexes.')); } } public function options_submit(&$form, &$form_state) { parent::options_submit($form, $form_state); switch ($form_state['section']) { case 'linked_path': $this->set_option('linked_path', $form_state['values']['linked_path']); break; case 'facet_field': $this->set_option('facet_field', $form_state['values']['facet_field']); break; case 'hide_block': $this->set_option('hide_block', $form_state['values']['hide_block']); break; } } public function options_summary(&$categories, &$options) { parent::options_summary($categories, $options); $options['linked_path'] = array( 'category' => 'block', 'title' => t('Search page path'), 'value' => $this->get_option('linked_path') ? $this->get_option('linked_path') : t('Use current path'), ); $field_options = $this->getFieldOptions(); $options['facet_field'] = array( 'category' => 'block', 'title' => t('Facet field'), 'value' => $this->get_option('facet_field') ? $field_options[$this->get_option('facet_field')] : t('None'), ); $options['hide_block'] = array( 'category' => 'block', 'title' => t('Hide block'), 'value' => $this->get_option('hide_block') ? t('Yes') : t('No'), ); } protected $field_options = NULL; protected function getFieldOptions() { if (!isset($this->field_options)) { $index_id = substr($this->view->base_table, 17); if (!($index_id && ($index = search_api_index_load($index_id)))) { $table = views_fetch_data($this->view->base_table); $table = empty($table['table']['base']['title']) ? $this->view->base_table : $table['table']['base']['title']; throw new SearchApiException(t('The "Facets block" display cannot be used with a view for @basetable. ' . 'Please only use this display with base tables representing search indexes.', array('@basetable' => $table))); } $this->field_options = array(); if (!empty($index->options['fields'])) { foreach ($index->getFields() as $key => $field) { $this->field_options[$key] = $field['name']; } } } return $this->field_options; } /** * Render the 'more' link */ public function render_more_link() { if ($this->use_more()) { $path = $this->get_option('linked_path'); $theme = views_theme_functions('views_more', $this->view, $this->display); $path = check_url(url($path, array())); return array( '#theme' => $theme, '#more_url' => $path, '#link_text' => check_plain($this->use_more_text()), ); } } public function query() { parent::query(); $facet_field = $this->get_option('facet_field'); if (!$facet_field) { return NULL; } $base_path = $this->get_option('linked_path'); if (!$base_path) { $base_path = $_GET['q']; } $limit = empty($this->view->query->pager->options['items_per_page']) ? 10 : $this->view->query->pager->options['items_per_page']; $query_options = &$this->view->query->getOptions(); if (!$this->get_option('hide_block')) { // If we hide the block, we don't need this extra facet. $query_options['search_api_facets']['search_api_views_facets_block'] = array( 'field' => $facet_field, 'limit' => $limit, 'missing' => FALSE, 'min_count' => 1, ); } $query_options['search_api_base_path'] = $base_path; $this->view->query->range(0, 0); } public function render() { if (substr($this->view->base_table, 0, 17) != 'search_api_index_') { form_set_error('', t('The "Facets block" display can only be used with base tables based on Search API indexes.')); return NULL; } $facet_field = $this->get_option('facet_field'); if (!$facet_field) { return NULL; } $this->view->execute(); if ($this->get_option('hide_block')) { return NULL; } $results = $this->view->query->getSearchApiResults(); if (empty($results['search_api_facets']['search_api_views_facets_block'])) { return NULL; } $terms = $results['search_api_facets']['search_api_views_facets_block']; $filters = array(); foreach ($terms as $term) { $filter = $term['filter']; if ($filter[0] == '"') { $filter = substr($filter, 1, -1); } elseif ($filter != '!') { // This is a range filter. $filter = substr($filter, 1, -1); $pos = strpos($filter, ' '); if ($pos !== FALSE) { $filter = '[' . substr($filter, 0, $pos) . ' TO ' . substr($filter, $pos + 1) . ']'; } } $filters[$term['filter']] = $filter; } $index = $this->view->query->getIndex(); $options['field'] = $index->options['fields'][$facet_field]; $options['field']['key'] = $facet_field; $options['index id'] = $index->machine_name; $options['value callback'] = '_search_api_facetapi_facet_create_label'; $map = search_api_facetapi_facet_map_callback($filters, $options); $facets = array(); $prefix = rawurlencode($facet_field) . ':'; foreach ($terms as $term) { $name = $filter = $filters[$term['filter']]; if (isset($map[$filter])) { $name = $map[$filter]; } $query['f'][0] = $prefix . $filter; // Initializes variables passed to theme hook. $variables = array( 'text' => $name, 'path' => $this->view->query->getOption('search_api_base_path'), 'count' => $term['count'], 'options' => array( 'attributes' => array('class' => 'facetapi-inactive'), 'html' => FALSE, 'query' => $query, ), ); // Override the $variables['#path'] if facetapi_pretty_paths is enabled. if (module_exists('facetapi_pretty_paths')) { // Get the appropriate facet adapter. $adapter = facetapi_adapter_load('search_api@' . $index->machine_name); // Get the URL processor and check if it uses pretty paths. $urlProcessor = $adapter->getUrlProcessor(); if ($urlProcessor instanceof FacetapiUrlProcessorPrettyPaths) { // Retrieve the pretty path alias from the URL processor. $facet = facetapi_facet_load($facet_field, 'search_api@' . $index->machine_name); $values = array(trim($term['filter'], '"')); // Get the pretty path for the facet and remove the current search's // base path from it. $base_path_current = $urlProcessor->getBasePath(); $pretty_path = $urlProcessor->getFacetPath($facet, $values, FALSE); $pretty_path = str_replace($base_path_current, '', $pretty_path); // Set the new, pretty path for the facet and remove the "f" query // parameter. $variables['path'] = $variables['path'] . $pretty_path; unset($variables['options']['query']['f']); } } // Themes the link, adds row to facets. $facets[] = array( 'class' => array('leaf'), 'data' => theme('facetapi_link_inactive', $variables), ); } if (!$facets) { return NULL; } return array( 'facets' => array( '#theme' => 'item_list', '#items' => $facets, ) ); } public function execute() { $info['content'] = $this->render(); $info['content']['more'] = $this->render_more_link(); $info['subject'] = filter_xss_admin($this->view->get_title()); return $info; } }