プログラムでビューにフィルター基準を追加する


18

filter criteriaプログラムで追加/変更したい。

たとえば、ビューの場合、値を動的に変更する必要がある「メールアドレス」フィルターを追加しました。現在のログインユーザーのメールIDに設定する必要があります。

それを達成する方法は?詳細については、添付の画像をご覧ください。助けてください。

ここに画像の説明を入力してください

回答:


24

使用のdevelモジュールをし、dpm($view)そしてdpm($query)あなたが「値」フィールドに「test@email.com」のように入れた後、あなたのPICで見つかりました。ビューのオブジェクト/配列構造を確認し、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);たらいいか教えてください。
シャフィウル

カスタムモジュールを作成し、上記の関数を配置します。ビューが有効になっている場合、フックが起動し、カスタムモジュールとDevelモジュールを有効にすると、ページの上部に$ viewと$ 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」メソッドを使用しましたが、ビューに引数を渡します。私はそれが誰かを助けることを願っています。必要に応じて、任意の引数タイプまたは値に置き換えることができます。

ビュー自体にコンテキストフィルターを追加しました(詳細なビュー設定フィールドセットから)。1つ目は「コンテンツ:分類用語IDがあります」です。2番目は「content:nid」で、「複数を許可」チェックボックスと「除外」チェックボックスがチェックされています(コンテキストフィルターポップアップの「詳細」フィールドセットから)。

args [] = '1'; //用語ID
args [] = '1 + 2 + 3'; //除外/含めるノードID

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

更新:コンテキストフィルター値内で、PHPコードを選択し、渡されたビュー引数を返す必要がある場合があることを忘れていました。

return $ view-> args [1];

1

Drupal 8ではViewExecutable::setHandler($display_id, $type, $id, $item)、プログラムでフィルターを設定するために使用できます。


4
この答えは、これがなぜ機能するかについてもう少し冗長になる可能性があります。多くの場合、ドキュメントページをリンクして引用します。これは、質問者が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.