Додайте КРИТЕРІЇ ФІЛЬТРУ в програми Перегляди програмно


18

Я хочу додати / змінити filter criteriaпрограмно.

Наприклад, для перегляду я додав фільтр "Адреса електронної пошти", значення якого потрібно динамічно змінювати, його потрібно встановити на поточний введений ідентифікатор електронної пошти користувача.

Як цього досягти? Будь ласка, дивіться додане зображення для отримання більш детальної інформації. Будь ласка, допоможіть.

введіть тут опис зображення

Відповіді:


24

Використовуйте модуль Develdpm($view) і dpm($query)після того, як ви введете на зразок "test@email.com" в поле "значення", знайдене на малюнку. Перегляньте структуру об'єкта / масиву подання та запиту з результатів розробки.

Потім використовуйте функцію 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);?
Шафіул

ви створюєте спеціальний модуль і розміщуєте вищевказану функцію. Гачок запускається, якщо перегляди увімкнено, і ви побачите $ view та $ query у верхній частині сторінки, як тільки ви ввімкнули спеціальний модуль та модуль Devel. Тоді просто змініть мій код, щоб ім’я машини вашого перегляду було
вказано

Це чудова відповідь. У Drupal 7 ви фактично робите: $ query-> where [1] ['умови'] [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

Бажано змінити їх у гачках, а не під час візуалізації, щоб ви не підривали продуктивність сайту та кешування. Мені потрібен вік, щоб зрозуміти, що пристрій_визначення_пре_бігу () запускається занадто пізно, вам потрібен гак_візування_пре_вз () .

Я знайшов посилання на використання $ 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". 2-ий - це "content: nid" з "разрешить несколько", і флажок "разрешить" виключити (з набору полів "more" у спливаючому контекстному фільтрі).

args [] = '1'; // Ідентифікатор терміна
args [] = '1 + 2 + 3'; // Ідентифікатори вузлів для виключення / включення

$ view = views_get_view ($ view_name);
$ view-> init ();
$ view-> set_display ($ дисплей);
$ view-> set_arguments ($ args);
$ view-> Execute ();
$ view-> результат

Оновлення: я забув згадати, в контекстних значеннях фільтра вам може знадобитися вибрати код php та повернути аргументи перегляду, передані в ньому. Наприклад:

повернути $ view-> args [1];

1

У Drupal 8 ви можете програмно ViewExecutable::setHandler($display_id, $type, $id, $item)встановити фільтр.


4
Ця відповідь може бути дещо докладнішою, чому це працює. Часто мені подобається посилання та цитування сторінок документації. Це допоможе запитувачу дізнатися більше про API Drupal та допоможе знайти інформацію для себе в майбутньому.
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поле дорівнює вибраній мові.

Більше інформації можна знайти в документах: kuk_views_query_alter


0

На основі @ Duncanmoo «s відповіді вище , що я відчував , що краще за все , я додав наступні фільтри на мій погляд , - подумав це було б корисно приклади в разі , якщо ви не намагаєтеся фільтр на основі посилального систематики , але замість цього на який посилаються особи або 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
        )
      );
    }
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.