Tambahkan FILTER KRITERIA dalam Tampilan Secara Programatis

18

Saya ingin menambah / memodifikasi filter criteriaprogram.

Misalnya, untuk tampilan, saya menambahkan filter "Alamat Email" yang nilainya diperlukan untuk berubah secara dinamis, diperlukan untuk mengatur ke id email pengguna yang login saat ini.

Bagaimana cara mencapainya? Silakan lihat gambar terlampir untuk detail lebih lanjut. Tolong bantu.

masukkan deskripsi gambar di sini

Shafiul
sumber

Jawaban:

24

Gunakan modul Devel dan dpm($view)dan dpm($query)setelah Anda memasukkan seperti "[email protected]" ke dalam bidang "nilai" yang ditemukan di foto Anda. Lihat struktur objek / array tampilan dan permintaan dari output devel.

Kemudian gunakan fungsi hook_views_query_alter(&$view, &$query)dalam modul Anda untuk menargetkan kondisi filter kondisi WHERE dan atur ke nilai yang Anda inginkan.

Sesuatu seperti:

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
    // '[email protected]' 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;
  }
}
Tenken
sumber
Terimakasih banyak! Bisakah Anda memberi tahu saya di mana saya pertama kali menulis dpm($view);?
Shafiul
Anda membuat modul khusus dan tempatkan fungsi di atasnya. hook akan menyala jika pandangan diaktifkan dan Anda akan melihat $ view dan $ query di bagian atas halaman setelah Anda mengaktifkan modul khusus dan modul Devel. Kemudian, ubah saja kode saya untuk memasukkan nama mesin tampilan Anda ke dalam ... dan
buatlah
Itu jawaban yang bagus. Dalam Drupal 7 Anda benar-benar melakukannya: $ query-> di mana [1] ['kondisi'] [2] ['nilai'] = $ pengguna-> email
Artur Kędzior
Secara pribadi saya pikir jawaban menggunakan kait di bawah ini jauh lebih baik drupal.stackexchange.com/a/200870/9634
kbrinner
6

Inilah alternatifnya:

$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();

Saya tahu Anda mungkin harus mengatur ini menggunakan beberapa metode esoteris, berbelit-belit, tetapi jika Anda hanya ingin akses cepat dan kotor tanpa mengacaukan ini akan membawa Anda ke sana.

rix
sumber
5

Akan lebih baik untuk mengubah ini di kait daripada pada waktu render sehingga Anda tidak merusak kinerja dan caching situs. Butuh waktu lama bagi saya untuk mengetahui bahwa hook_views_pre_build () sudah terlambat, Anda perlu hook_views_pre_view () .

Saya menemukan referensi untuk menggunakan $ view-> add_item () tetapi berjuang untuk contoh, di bawah ini adalah solusi saya untuk memfilter sekumpulan istilah taksonomi untuk hanya menyertakan vocab tertentu:

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);
    }
  }
}

Edit catatan : Komentar pada grup do ini membantu saya mengetahui cara mendapatkan filter tampilan menggunakan $view->display_handler->get_option('filters')dan kemudian menimpanya menggunakan $view->display_handler->override_option('filters', $filters);.

Duncanmoo
sumber
2

Saya pernah mengalami masalah serupa tetapi di mana mencoba meneruskan beberapa argumen ke filter. Saya telah menggunakan metode "views_get_view", tetapi meneruskan argumen ke tampilan. Saya harap ini membantu seseorang. Anda dapat mengganti segala jenis argumen atau nilai dengan kebutuhan Anda:

Saya telah menambahkan filter kontekstual ke tampilan itu sendiri (dari bidang pengaturan tampilan muka). Yang pertama adalah "konten: memiliki ID istilah taksonomi". Yang ke-2 adalah "content: nid" dengan "allow multiple" dicentang dan "exclude" checkbox dicentang (dari field 'more' dalam pop-up filter kontekstual).

args [] = '1'; // ID Istilah
args [] = '1 + 2 + 3'; // Node ID untuk mengecualikan / memasukkan

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

Pembaruan: Saya lupa menyebutkan, dalam nilai filter kontekstual, Anda mungkin perlu memilih kode php dan mengembalikan argumen tampilan yang dilewatkan. Misalnya:

return $ view-> args [1];
Seb
sumber
1

Di Drupal 8 Anda dapat menggunakan ViewExecutable::setHandler($display_id, $type, $id, $item)untuk mengatur filter secara terprogram.

vlledo
sumber
4
Jawaban ini bisa sedikit lebih bertele-tele tentang mengapa ini bekerja. Seringkali saya suka menautkan dan mengutip halaman dokumentasi. Ini akan membantu penanya mempelajari lebih lanjut tentang API Drupal dan membantu menemukan informasi untuk diri mereka sendiri di masa depan.
mradcliffe
1

Berikut adalah contoh tentang bagaimana kriteria filter dapat ditambahkan secara pemrograman di 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(), '=');
  }
}

Kueri di atas akan menambahkan kriteria yang memfilter simpul di mana field_custom_criteriabidang sama dengan bahasa yang saat ini dipilih.

Info lebih lanjut dapat ditemukan di dokumen: hook_views_query_alter

estrar
sumber
0

Berdasarkan jawaban @ Duncanmoo di atas yang saya rasa terbaik, saya menambahkan filter berikut ini ke pandangan saya - pikir ini akan menjadi contoh yang berguna jika Anda tidak mencoba memfilter berdasarkan taksonomi yang dirujuk tetapi pada entitas yang direferensikan atau sebuah 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
        )
      );
    }
  }
}
kbrinner
sumber