프로그래밍 방식으로 뷰에서 FILTER CRITERIA 추가


18

filter criteria프로그래밍 방식 으로 추가 / 수정하고 싶습니다 .

예를 들어,보기를 위해 동적으로 변경하기 위해 값이 필요한 "이메일 주소"필터를 추가했습니다. 현재 로그인 한 사용자의 이메일 ID로 설정해야합니다.

그것을 달성하는 방법? 자세한 내용은 첨부 된 이미지를 참조하십시오. 도와주세요.

여기에 이미지 설명을 입력하십시오

답변:


24

사용 (STABLE)의 모듈을 dpm($view)하고 dpm($query)당신이 "값"필드에 "test@email.com"처럼 넣어 후 그림에서 발견. devel 출력에서 ​​뷰 및 쿼리의 객체 / 배열 구조를 참조하십시오.

그런 다음 hook_views_query_alter(&$view, &$query)모듈 의 함수 를 사용하여 WHERE 조건 필터 조건을 대상으로하고 원하는 값으로 설정하십시오.

다음과 같은 것 :

function MYMODULE_views_query_alter(&$view, &$query) {
  global $user;
  dpm($view, __FUNCTION__);
  dpm($query, __FUNCTION__);
  if ($view->name === 'your_view_machine_name') {
    // This will only work as-is if you always have something in the filter by
    // default, I guess. This hook runs always so you could just put
    // 'test@test.com' as the email to filter by in views and this
    // will always override it. I'm sure there is a cleaner way to put
    // the filter dynamically at runtime. But i think thats more complex
    // php that customizes a view.
    //
    // The index 2 below is the index of the condition for the email filter.
    // Your $query structure may be different in your dpm() of the View $query.
    $query->where[1]['conditions'][2]['field']['value'] = $user->email;
  }
}

많은 감사합니다! 내가 어디에서 먼저 쓰는지 말해 줄래 dpm($view);?
Shafiul

사용자 정의 모듈을 만들고 위의 기능을 배치하십시오.보기가 활성화되면 후크가 시작되고 사용자 정의 모듈과 Devel 모듈을 활성화하면 페이지 상단에 $ view 및 $ query가 표시됩니다. 그런 다음 뷰의 머신 이름을 지정하도록 내 코드를 변경하고 $ query 값을 정확한 쿼리와 함께 사용하도록 설정하십시오.
tenken

좋은 답변입니다. Drupal 7에서 실제로 : $ query-> where [1] [ 'conditions'] [2] [ 'value'] = $ user-> email
Artur Kędzior

개인적으로 나는 아래 고리를 사용하는 대답이 훨씬 좋습니다 drupal.stackexchange.com/a/200870/9634
kbrinner

6

대안은 다음과 같습니다.

$view = views_get_view('view_machine_name');
$view->init_display('default');
$view->display_handler->display->display_options['filters']['your_filter_name']['default_value'] = 'your_value';
$view->is_cacheable = FALSE;  
$view->execute();
print $view->render();

난 당신이 아마도 난해하고 복잡한 방법을 사용하여 이것을 설정해야한다는 것을 알고 있지만, 주위를 어지럽히 지 않고 빠르고 더러운 액세스를 원한다면 거기에 도착할 것입니다.


5

사이트 성능과 캐싱을 손상시키지 않도록 렌더링 시간이 아닌 후크에서 이들을 변경하는 것이 좋습니다. 그 알아낼 나 나이를 툭 ) (hook_views_pre_build , 당신이 필요로 너무 늦게 발사 hook_views_pre_view () .

$ view-> add_item () 사용에 대한 참조를 찾았 지만 예를 들어 어려움을 겪었습니다. 아래는 특정 용어 만 포함하도록 분류 용어 세트를 필터링하는 솔루션입니다.

function MODULENAME_views_pre_view(&$view, &$display_id, &$args) {

  if ($view->name == 'VIEWNAME' && $display_id == 'DISPLAYID') {
    // Add all the terms of a vocabulary to the terms listing widget select field
    $vids = array();
    $vocab = taxonomy_vocabulary_machine_name_load('vocab_name');
    $vids[ $vocab->vid ] = $vocab->vid;

    // Get the existing filters
    $filters = $view->display_handler->get_option('filters');

    if (empty($filters['vid'])) {
      // There is no vid filter so we have to add it
      $view->add_item(
        $view->current_display,
        'filter',
        'taxonomy_term_data',
        'vid',
        array(
          'operator' => 'in',
          'value' => $vids,
          'group' => 1
        )
      );
    }
    else {
      // Add to pre-existing filter
      foreach($vids as $vid) {
        $filters['vid']['value'][ $vid ] = $vid;
      }
      $view->display_handler->override_option('filters', $filters);
    }
  }
}

참고 편집 : do 그룹에 대한 이 의견 을 통해 뷰 필터를 사용하여 뷰 필터를 가져 $view->display_handler->get_option('filters')와서이를 재정의하는 방법을 알아 냈습니다 $view->display_handler->override_option('filters', $filters);.


2

비슷한 문제가 있었지만 여러 인수를 필터에 전달하려고합니다. "views_get_view"메소드를 사용했지만 뷰에 인수를 전달했습니다. 누군가에게 도움이되기를 바랍니다. 필요에 따라 인수 유형 또는 값을 대체 할 수 있습니다.

고급 뷰 설정 필드 세트에서 컨텍스트 필터를 뷰 자체에 추가했습니다. 첫 번째는 "컨텐츠 : 분류 용어 ID가 있습니다"입니다. 두 번째 것은 "콘텐츠 : nid"이며 "여러 개 허용"을 선택하고 "제외"확인란을 선택합니다 (컨텍스트 필터 팝업의 'more'필드에서).

인수 [] = '1'; // 용어 ID
인수 [] = '1 + 2 + 3'; // 제외 / 포함 할 노드 ID

$ view = views_get_view ($ view_name);
$ view-> init ();
$ view-> set_display ($ display);
$ view-> set_arguments ($ args);
$ view-> execute ();
$ view-> 결과

업데이트 : 컨텍스트 필터 값 내에서 PHP 코드를 선택하고 전달 된보기 인수를 반환해야 할 수도 있습니다. 예 :

return $ view-> args [1];

1

Drupal 8에서는 ViewExecutable::setHandler($display_id, $type, $id, $item)프로그래밍 방식으로 필터를 설정할 수 있습니다 .


4
이 대답은 왜 이것이 작동하는지에 대해 좀 더 장황 할 수 있습니다. 종종 문서 페이지를 링크하고 인용하고 싶습니다. 이는 asker가 Drupal API에 대해 더 많이 배우고 미래에 스스로 정보를 찾는 데 도움이됩니다.
mradcliffe

1

다음은 Drupal 8에서 프로그래밍 방식으로 필터 기준을 추가하는 방법에 대한 예입니다.

/**
 * @param ViewExecutable $view
 * @param QueryPluginBase $query
 *
 * Sets a custom custom filter criteria (takes current language into account)
 */
function MODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->storage->id() === 'my_view_id') {
    $query->addWhere(0, 'node__field_custom_criteria.field_custom_criteria_value', \Drupal::languageManager()->getCurrentLanguage()->getId(), '=');
  }
}

위 쿼리는 field_custom_criteria필드가 현재 선택된 언어와 동일한 노드를 필터링하는 기준을 추가합니다 .

자세한 정보는 문서에서 찾을 수 있습니다 : hook_views_query_alter


0

위의 @ Duncanmoo대답 이 가장 좋았다고 생각하여 다음 필터를 내 견해에 추가했습니다. 참조 된 분류법을 기준으로 필터링하지 않고 참조 된 엔티티 또는 NID :

function [MYMODULE]_views_pre_view(&$view, &$display_id, &$args) {
  if (($view->name == '[your view name]') && ($display_id == '[your display id]')) {
    // Get referenced service - example for entity reference.
    $node = menu_get_object();
    $node_wrapper = entity_metadata_wrapper('node', $node->nid);
    $referenced_service = $node_wrapper->field_service_ref->value();
    // Add service id as a filter to view.
    $filters = $view->display_handler->get_option('filters');
    if (empty($filters['field_service_ref_target_id'])) {
      // Only display operations nodes that reference the same service.
      $view->add_item(
        $display_id,
        'filter',
        'field_data_field_service_ref',
        'field_service_ref_target_id',
        array(
          'operator' => '=',
          'value' => ['value' => $referenced_service->id],
          'group' => 1
        )
      );
    }
    // Add nid as a filter to view - example for NID filter
    if (empty($filters['nid'])) {
      // Don't include current operation in list of related operations.
      $view->add_item(
        $display_id,
        'filter',
        'node',
        'nid',
        array(
          'operator' => '!=',
          'value' => ['value' => $node->nid],
          'group' => 1
        )
      );
    }
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.