Commit bfae1705 authored by swentel's avatar swentel
Browse files

Issue #2838153: first (basic) port.

parent 7bbd3731
Welcome to Views Exposed Filters Summary
Views Exposed Filters Summary
=============================
This module allows to display Field names and Values of exposed filters that user selected for the view. This widget can be displayed in Header/Footer area. User can configure which exposed filters will be displayed and which remain hidden from user.
This module allows to display Field names and Values of exposed filters which
the user selected for the view. This widget can be displayed in Header/Footer
area. Admins can configure which exposed filters will be displayed and which
remain hidden from user.
Requirements
============
- Views Module
http://drupal.org/project/views
- Views module, included in Drupal Core
Installation
============
- Install module
- Add Views exposed filters summary: Exposed filters summary to Header or Footer
- Install module
- Add Views exposed filters summary to Header or Footer
- Select which exposed filters to show to end user https://www.drupal.org/files/issues/views-exposed-filters-summary-configuration.png
# Schema for views exposed filters summary.
views.area.views_filters_summary:
type: views_area
label: 'View filters summary'
mapping:
filters:
type: sequence
label: 'The filters to show'
sequence:
type: string
label: 'Field name'
show_labels:
type: boolean
label: 'Show labels'
show_operators:
type: boolean
label: 'Show operators'
......@@ -4,27 +4,24 @@
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
margin-right: 0.5em;
margin-bottom: 6px;
padding: 0 1px 0 6px;
padding: 0 1px 0 6px;
border: 1px solid #8C1515;
}
.exposed-filter-value a.remove-filter {
border: none;
background-color: #ededed;
font-size: 18px;
padding: 1px 8px 0 8px;
margin-left: 4px;
background-color: #ededed;
font-size: 18px;
padding: 1px 8px 0 8px;
margin-left: 4px;
color: #000;
vertical-align: middle;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
-moz-border-radius: 3px;
}
.exposed-filter-selected {
font-style: italic;
......
<?php
namespace Drupal\views_filters_summary\Plugin\views\area;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\area\AreaPluginBase;
/**
* Views filters summary.
*
* @ingroup views_area_handlers
*
* @ViewsArea("views_filters_summary");
*/
class ViewsFiltersSummary extends AreaPluginBase {
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['filters'] = ['default' => NULL];
$options['show_labels'] = ['default' => NULL];
$options['show_operators'] = ['default' => NULL];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$this->view->initHandlers();
$filter_options = array();
foreach ($this->view->filter as $id => $handler) {
if ($handler->isExposed()) {
$filter_options[$id] = $handler->adminLabel();
}
}
$form['filters'] = [
'#type' => 'select',
'#title' => $this->t('Filters'),
'#multiple' => TRUE,
'#options' => $filter_options,
'#default_value' => $this->options['filters'],
'#description' => $this->t('Choose the filters, if none are selected, all will be used.'),
//'#process' => array('form_process_select'),
];
$form['show_labels'] = [
'#type' => 'checkbox',
'#title' => $this->t('Display labels'),
'#default_value' => $this->options['show_labels'],
'#description' => $this->t('If checked, the labels will be displayed, otherwise just the value is printed.'),
];
$form['show_operators'] = [
'#type' => 'checkbox',
'#title' => $this->t('Display operators'),
'#default_value' => $this->options['show_operators'],
'#description' => $this->t('If checked, the operators will be displayed, rather than just foo : bar.'),
];
}
/**
* {@inheritdoc}
*/
public function render($empty = FALSE) {
$summary = [];
$selected_filters = !empty($this->options['filters']) ? $this->options['filters'] : [];
foreach ($this->view->filter as $id => $filter) {
// Ignore non exposed filters, not selected filters or empty values.
if (!$filter->isExposed() || ($selected_filters && !isset($selected_filters[$id])) || empty($filter->value)) {
continue;
}
$summary[] = [
'label' => $id,
'value' => $filter->value[0],
];
}
// TODO add css
return [
'#theme' => 'views_filters_summary',
'#summary' => $summary,
];
}
}
{#
/**
* @file
* Default theme implementation to display views exposed filters summary.
*
* Available variables:
* - summary: the array of selected filters.
*/
#}
<div id="exposed-filters-summary">
{%- for item in summary -%}
<span class="exposed-filter-value" >
{{ item.label }}: {{ item.value }}
</span>
{%- endfor -%}
</div>
<?php
/**
* @file
* Default theme implementation to display views exposed filters summary.
*
* Available variables:
* - $summary: the array of filters.
* - $result (not implemented yet): renderable array of $summary.
* - $path: A result of request_path() function execution.
*/
?>
<div id="exposed-filters" style="margin-top:1em;">
<?php
foreach ($summary as $field_name => $filter): ?>
<span class="exposed-filter-value" >
<?php
print $filter['label'];
$filter_op = ($filter['op'] == 'in' || $filter['op'] == 'or');
$filter_op = empty($filter['op']) || $filter_op;
if ($filter_op && count($filter['value']) == 1):
print ": ";
else:
print $filter['opLabel'];
endif;
$url = url($path, array('query' => $filter['query_parameters']));
$classes = implode(' ', $filter['attributes']['class']);
?>
<span class="exposed-filter-selected <?php print $classes; ?>"><?php print $filter['output_value']; ?></span>
<a class="remove-filter" href="<?php print $url; ?>">X</a>
</span>
<?php endforeach; ?>
</div>
name = Views Exposed Filters Summary
description = Plugin to display summary of selected exposed filters in header or footer area of a view.
core = 7.x
package = Views
dependencies[] = views
files[] = views_exposed_filters_summary_handler_area_exposed_filters_summary.inc
stylesheets[all][] = views_exposed_filters_summary.css
<?php
/**
* @file
* Provide views data for views_exposed_filters_summary.module.
*/
/**
* Implements hook_views_data_alter().
*/
function views_exposed_filters_summary_views_data_alter(&$data) {
$data['views_exposed_filters_summary'] = array(
'table' => array(
'group' => t('Views exposed filters summary'),
'join' => array('#global' => array()),
),
);
$data['views_exposed_filters_summary']['exposed_filters_summary'] = array(
'title' => t('Exposed filters summary'),
'help' => t('Shows result summary, for example the items per page.'),
'area' => array(
'handler' => 'ViewsExposedFiltersSummaryHandlerAreaExposedFiltersSummary',
),
);
}
<?php
/**
* @file
* Contains ViewsExposedFiltersSummaryHandlerAreaExposedFiltersSummary.
*/
/**
* ViewsExposedFiltersSummaryHandlerAreaExposedFiltersSummary class.
*/
class ViewsExposedFiltersSummaryHandlerAreaExposedFiltersSummary extends views_handler_area {
/**
* {@inheritdoc}
*/
public function option_definition() {
$options = parent::option_definition();
$options['filters'] = array('default' => NULL);
$options['show_operators'] = array('default' => NULL);
return $options;
}
/**
* {@inheritdoc}
*/
public function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
$this->view->init_handlers();
$filter_options = array();
foreach ($this->view->filter as $id => $handler) {
if ($handler->is_exposed()) {
$filter_options[$id] = $handler->ui_name();
}
}
$form['filters'] = array(
'#type' => 'select',
'#title' => t('Filters'),
'#multiple' => TRUE,
'#options' => $filter_options,
'#default_value' => $this->options['filters'],
'#description' => t('Choose the filters, if none are selected, all will be used'),
'#process' => array('form_process_select'),
);
$form['show_operators'] = array(
'#type' => 'checkbox',
'#title' => t('Display operators'),
'#default_value' => $this->options['show_operators'],
'#description' => t('If checked, the operators will be displayed, rather than just foo : bar'),
);
}
/**
* {@inheritdoc}
*/
public function render($empty = FALSE) {
$summary = $this->viewsExposedFiltersSummary($this->view);
return theme('views_exposed_filters_summary_results', array('summary' => $summary));
}
/**
* Returns an array of summary information.
*
* @param \view $view
* Views object.
*
* @return array
* An array of summary data.
*/
protected function viewsExposedFiltersSummary(view $view) {
$operators = array(
'allwords' => t('Contains all words from'),
'or' => t('One of'),
'and' => t('All of'),
'not' => t('Not in'),
'word' => t('Contains a word from'),
'in' => t('In'),
'not in' => t('Not In'),
);
// First we get all filters in a view in array $filters_summary.
$filters_summary = array();
$selected_filters = !empty($this->options['filters']) ? $this->options['filters'] : array();
$show_operators = $this->options['show_operators'];
$names = array();
foreach ($view->filter as $filter_key => $filter) {
// Deal only with exposed filters.
if ($filter->options['exposed'] === FALSE) {
continue;
}
$field = $filter->field;
$name = $field;
if (array_key_exists($field, $names)) {
$name = $field . '_' . $names[$field];
$names[$field]++;
}
else {
$names[$field] = 1;
}
if (!empty($filter->options) && !empty($filter->options['exposed']) && $filter->options['expose']['multiple']) {
$name = $name . '[]';
}
if ($selected_filters && !isset($selected_filters[$filter_key])) {
continue;
}
$op = '=';
$op_label = '=';
if (!$filter->no_operator) {
$op = $filter->operator;
if (isset($operators[$op])) {
$op_label = $operators[$op];
}
else {
$op_label = $op;
}
}
// Make sure that we do not display exposed filters that were not used.
// E.g., check if a filter has a value.
if (!empty($filter->value)) {
if ($filter->table == 'node' && in_array($filter->field, array('title'))) {
$filters_summary[$filter_key] = array(
'label' => check_plain($filter->options['expose']['label']),
'value' => array($filter->value),
'op' => $op,
'opLabel' => $op_label,
'field' => $name,
);
continue;
}
// Get definition of field name.
$field_name = FALSE;
if (isset($filter->definition['field_name'])) {
$field_name = $filter->definition['field_name'];
$field_info = field_info_field($field_name);
}
// Get the type of field, or else use the handler for the fields which don't have a fieldname.
if ($field_name) {
$fieldtype = $field_info['type'];
}
else {
$fieldtype = $filter->definition['handler'];
}
// Get the best label possible.
$label = isset($filter->definition['title short']) ?
$filter->definition['title short'] :
$filter->definition['title'];
if (isset($filter->options) && isset($filter->options['expose'])) {
if (!empty($filter->options['expose']['label'])) {
$label = $filter->options['expose']['label'];
}
}
$filter_summary = array(
'label' => check_plain($label),
'value' => $filter->value,
'raw_value' => $filter->value,
'op' => $op,
'opLabel' => $op_label,
'field' => $name,
);
if (is_array($filter_summary['value'])) {
foreach ($filter_summary['value'] as $key => $value) {
$filter_summary['value'][$key] = check_plain($value);
}
}
else {
$filter_summary['value'] = check_plain($filter_summary['value']);
}
$include_filter = TRUE;
// Check which type of filter it is.
switch ($fieldtype) {
case 'text_with_summary';
case 'text';
if (empty($filter_summary['value'])) {
$include_filter = TRUE;
break;
}
else {
$filter_summary['value'] = array($filter_summary['value']);
}
break;
case 'list_text':
if (!empty($field_info['settings']['allowed_values'])) {
foreach ($filter_summary['value'] as $key => $value) {
$filter_summary['value'][$key] = $field_info['settings']['allowed_values'][$value];
}
}
break;
case 'taxonomy_term_reference':
case 'views_handler_filter_term_node_tid':
case 'views_handler_filter_term_node_tid_depth':
foreach ($filter_summary['value'] as $key => $value) {
$term = taxonomy_term_load($value);
if ($term) {
$filter_summary['value'][$key] = $term->name;
}
}
break;
case 'list_boolean':
foreach ($filter_summary['value'] as $key => $value) {
$filter_summary['value'][$key] = $filter_summary['value'][$key] == '1'
|| $filter_summary['value'][$key] == 'Yes' ? t('Yes') : t('No');
}
break;
case 'datetime':
case 'datestamp':
case 'number_integer':
case 'number_float':
case 'number_decimal':
$operator = array(
'=',
'>',
'>=',
'<',
'<=',
'!=',
'regular_expression',
);
if (in_array($op, $operator)) {
if (empty($filter_summary['value']['value'])) {
$include_filter = FALSE;
break;
}
$filter_summary['value'] = array($filter_summary['value']['value']);
}
elseif ($filter->operator == 'between') {
if (empty($filter->value['min'])) {
if (empty($filter->value['max'])) {
$include_filter = FALSE;
break;
}
else {
$filter_summary['opLabel'] = $fieldtype == 'datetime' ? t('before') : t('less than');
$filter_summary['value'] = array($filter_summary['value']['max']);
}
}
else {
if (empty($filter->value['max'])) {
$filter_summary['opLabel'] = $fieldtype == 'datetime' ? t('after') : t('more than');
$filter_summary['value'] = array($filter_summary['value']['min']);
}
else {
$filter_summary['opLabel'] = 'between';
$filter_summary['value'] = array(
$filter_summary['value']['min'],
$filter_summary['value']['max'],
);
}
}
}
elseif ($filter->operator == 'not between') {
if (empty($filter->value['min'])) {
if (empty($filter->value['max'])) {
$include_filter = FALSE;
break;
}
else {
$filter_summary['opLabel'] = t('greater than');
$filter_summary['value'] = array($filter_summary['value']['max']);
}
}
else {
if (empty($filter->value['max'])) {
$filter_summary['opLabel'] = t('less than');
$filter_summary['value'] = array($filter_summary['value']['min']);
}
else {
$filter_summary['opLabel'] = 'not between';
$filter_summary['value'] = array(
$filter_summary['value']['min'],
$filter_summary['value']['max'],
);
}
}
}
break;
case 'entityreference':
$items = entity_load($field_info['settings']['target_type'], array_values($filter->value));
$res = array();
foreach ($items as $item) {
$uri = entity_uri($field_info['settings']['target_type'], $item);
$title = entity_label($field_info['settings']['target_type'], $item);
if (!empty($uri) && isset($uri['path'])) {
$res[] = '<a href="' . $uri['path'] . '">' . $title . '</a>';
}
else {
$res[] = $title;
}
}
$filter_summary['value'] = $res;
break;
case 'views_handler_filter_combine':
$filter_summary['value'] = array($filter->value);
break;