视图3以编程方式删除暴露的过滤器


9

我有几种节点类型,每种类型都引用了不同的分类术语词汇。对于显示类别,我使用taxonomy_display模块。

例如,我们有两类:球杆和台球。

提示有价格,价格和木质过滤器。但是球没有木质过滤器。

因此,如果taxonomy_term tid引用了台球词汇,则需要删除木质过滤器。

因此,我需要以编程方式删除许多公开的过滤器之一。

function modulename_views_pre_view(&$view, &$display_id, &$args) {
  // Some custom logic wich field_info_instances checking ...
  $filter_field = 'filter_id';
  // Removes from everywhere where i can find filter or filters properties
  unset($view->display[$view->current_display]->display_options['filters'][$filter_field]);
  unset($view->display[$view->current_display]->handler->options['filters'][$filter_field]);
  unset($view->display_handler->display->display_options['filters'][$filter_field]);
  unset($view->display_handler->options['filters'][$filter_field]);
}

筛选器字段删除成功,但是我有php通知:

  Notice: Undefined index: field_wood_reference_tid in function views_handler_filter_term_node_tid->exposed_validate()

我也尝试删除hook_pre_execute()中的字段,但结果相同:

function modulename_views_pre_execute(&$view) {
  $filter_field = 'filter_id';
  unset($view->display_handler->handlers['filter'][$filter_field]);
  unset($view->filter[$filter_field]);
}

还可以尝试使用override_option()方法,例如此处-http://groups.drupal.org/node/82219,但完全没有结果。

有什么建议么?请帮助=)


感谢大家的答复,但我仍然没有答案。也许不清楚?=(


您是否尝试过hook_views_pre_render()?您还可以根据jQuery的选择显示/隐藏相关的过滤器。
enzipher

嗨,我知道您的解决方案可以,但是没有正确的方法。因此,我什至可以使用CSS条件将其隐藏...尝试解释。每种代码都应放置在应放置的位置。对于此问题,如果我在渲染之前或之后隐藏暴露的滤镜,则视图仍会对其进行处理。如果我尝试添加查询字符串,如smt ?filter_id=val,则视图返回空显示或非法选择错误...
Oleg Sherbakov

你试过我的答案了吗?
Mathankumar

我不需要更改表单(我知道您的变体有效),我想将视图对象修改为与您的结果相似,但要早于表单构建。
Oleg Sherbakov

Answers:



1

这是经过测试的代码段,可让您使用Scott Thomas提到的form alter从暴露的窗体中删除过滤器,

/**
 *Implements hook_form_FORM_ID_alter().
 */
function hook_form_views_exposed_form_alter(&$form, &$form_state) {
  $filter_field = 'filter_id';
  // Get the filters list for the current view. Here page_1 is the display ID.
  $filters = $form_state['view']->get_items('filter', 'page_1');
  if (isset($filters[$filter_field])) {
    $info_key = 'filter-' . $filter_field;
    unset($form[$filter_field], $form['#info'][$info_key]);
  }     
}

除了删除表单字段之外,您还需要删除$ form ['#info']中可用的特定过滤器的信息,以便它也将删除标签。如果仅删除表单元素,那么即使删除了该字段也将显示过滤器标签。因此,请始终确保也要删除此信息。

根据需要进行修改。如果您想针对特定视图执行此操作,请为此添加一个条件,例如,

if ($form_state['view']->name == 'view_name') {
  // DO your operation.
}

在这里$ form_state ['view']将为您提供当前正在处理的视图对象。

希望这可以帮助。


这是唯一为我隐藏标签和字段小部件的解决方案,并且以块中的公开过滤器形式工作。
xenophyle

1

请按照以下步骤

  1. 首先在自定义模块中编写一个hook_form_alter
  2. 接下来尝试以下代码

    unset($ form ['#info'] ['your_field_name']); $ form ['your_field_name'] ['#access'] ='FALSE';

希望能有所帮助。


1

您也可以使用模板文件删除暴露的过滤器。

使用以下命令:

cp sites/all/modules/contrib/views/theme/views-view.tpl.php sites/all/themes/costa/templates/views/views-view--<machine_name>.tpl.php

在模板文件中找到以下代码:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

并将其删除。您暴露的过滤器将从显示中删除,但可以继续工作,并在URL中传递适当的参数。


谢谢,但我正在等待D8,它使用核心表单API来构建暴露的过滤器:)
Oleg Sherbakov

0

如果我错了,请纠正我,因为我不确定是否完全了解您的问题。因此,您想根据其他隐藏滤镜的值在视图中隐藏一个暴露滤镜吗?如果是这样,您可以尝试使用“ 视图相关过滤器”模块。我用了好几次,就可以了。

您可以检查我们的魔鬼Lullabot 对这个模块的评论

如果您确实需要在代码中执行此操作,则暴露选项应该起作用:filter [$ filter_id]-> options ['exposed'] = FALSE;


如果当前内容类型没有此(过滤的)字段,我想隐藏暴露的过滤器。尝试您的代码片段时,$view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE;我遇到致命错误- PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766。我认为它是正确的行为,因为如果未公开过滤器,则它也需要默认值。有任何想法吗?
Oleg Sherbakov

pastebin.com/f1FKgUde这是我的代码,也许它将比我的英语更清楚
Oleg Sherbakov

0

以下是在hook_form_alter中为我完成的操作:

$info_key = 'filter-' . $fieldName;
unset($form[$fieldName], $form['#info'][$info_key], $form_state['view']->display_handler->options['filters'][$fieldName], $form_state['view']->display_handler->handlers['filter'][$fieldName], $form_state['view']->filter[$fieldName]);

0

方法一

通过使用hook_views_query_alter()。请参见以下示例:

<?php
/**
 * Implements hook_views_query_alter().
 */
function foo_views_query_alter(&$view, &$query) {

  if ($view->name == 'foo_view') {

    // Allow any distance when the postcode it is not specified.
    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') { 
      // Scan through the query.
      foreach ($query->where as $condition_group_key => &$condition_group) {
        foreach ($condition_group['conditions'] as $condition_key => &$condition) {
          $search_name = '(COALESCE(ACOS(';
          if (is_string($condition['field']) && strstr($condition['field'], $search_name) !== FALSE) {
            // Remove filter from the query.
            unset($query->where[$condition_group_key]['conditions'][$condition_key]);
          }
        } // end: foreach
      } // end: foreach
    } // end: if


    /*
     * Change the field conditions.
     * Possible field values: 1, 2, 3
     * Logic: When 3 is selected, then display 1, 2 and 3.
     */
    switch (@$view->display_handler->handlers['filter']['field_123_value']->value[0]) {

      case 3:
        foreach ($query->where as $condition_group_key => &$condition_group) {
          foreach ($condition_group['conditions'] as $condition_key => &$condition) {
            if($condition['field'] == 'field_data_field_123.field_123_value') {
              unset($query->where[$condition_group_key]['conditions'][$condition_key]);
              $query->where[] = array(
                  'conditions' => array(
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 1,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 2,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 3,
                          'operator' => "=",
                      ),
                  ),
                  'args' => array(),
                  'type' => 'OR',
              );
            }
          }
        } // end: foreach
        break;

    } // end: switch

  } // end: if
}

方法2

通过使用hook_views_pre_execute和自定义函数来查看示例,该函数试图找到正确的字段条件并返回对该条件的引用:

/**
 * Implements hook_views_pre_execute().
 */
function foo_views_pre_execute(&$view) {

  if ($view->name == 'foo_view') {


    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'field_data_field_123.field_123_value',
      $filter
    );

    // We want our filter to work as a bit mask.
    $filter[0]['operator'] = '&';

    unset ($filter);

    // Example of finding Proximity filter condition
    $search_name = '(COALESCE(ACOS(';

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      $search_name,
      $filter
    );

    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') {
      // Allowing any distance.
      $filter[0]['value'][':distance'] = 10000000;
    }
    else {
      $filter[0]['value'][':distance'] = 80000;
    }

    unset ($filter);


    // Fetching single record?

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'node.nid',
      $filter
    );

    if (!empty($_GET['nid'])) {
      $filter[0]['value'] = (int) $_GET['nid'];
    }
    else {
      $filter[0]['operator'] = '<>';
    }

    unset ($filter);                                                        

    // echo '<pre style="font-size:11px;font-family: Monaco">'; print_r($view->build_info['query']); exit;
  }
}

/**
 * Custom function to find the field condition within the view
 */
function foo_get_view_filter_recursively($view, &$conditions, $field_name, &$filter) {

  if (!empty($conditions)) {

    foreach ($conditions as &$condition) {
      if ($condition instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } else if ($condition['field'] instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition['field']->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } elseif (is_string($condition['field']) && strstr($condition['field'], $field_name) !== FALSE) {
        @$filter = array(&$condition);
        return TRUE;
      }
    } // end: foreach

  } // end: if

  return FALSE;
}

0

我正在从模板文件中删除它。覆盖views-view.tpl.php并从其中删除以下代码:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

0

我认为操作是在正确的轨道上。我也有类似的情况,没有暴露的过滤器,所以我不能使用hook_form_alter方法。这是其他遇到此问题的示例代码:

$view->set_item($view->current_display, 'filter', $filter_id, null);

视图对象没有remove_item功能,只是简单地在代码中声明您可以将其设置为null以便删除包含过滤器的项目: views/includes/view.inc在线2526

这是针对特定视图和显示的所有人的完整示例:

/**
 * Implements HOOK_views_pre_view().
 */
function HOOK_views_pre_view(&$view) {
  if($view->name == 'VIEW_MACHINE_NAME') {
    switch($view->current_display) {
      case 'VIEW_DISPLAY_MACHINE_NAME':
        $view_filters = $view->display_handler->get_option('filters');
        foreach ($view_filters as $filter_id => $filter) {
          if ($filter_id == 'my_filter') {
            $view->set_item($view->current_display, 'filter', $filter_id, null);
          }
        }
      break;
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.