Добавить критерии фильтра в представления программно


18

Я хочу добавить / изменить filter criteriaпрограммно.

Например, для представления я добавил фильтр «Адрес электронной почты», значение которого необходимо для динамического изменения, его необходимо установить для текущего идентификатора электронной почты пользователя, вошедшего в систему.

Как этого добиться? Пожалуйста, смотрите прикрепленное изображение для более подробной информации. Пожалуйста помоги.

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

Ответы:


24

Используйте Devel модуль и 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);?
Шафиул

Вы создаете пользовательский модуль и помещаете вышеупомянутую функцию в него. Хук сработает, если представления включены, и вы увидите $ view и $ query вверху страницы, как только вы включите пользовательский модуль и модуль Devel. Затем просто измените мой код, чтобы машина вашего представления
назвала

Это отличный ответ. В Drupal 7 вы фактически делаете: $ query-> где [1] ['условия'] [2] ['значение'] = $ пользователь-> электронная почта
Артур Кендзиор

Лично я думаю, что ответ с использованием описанных
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", но передавал аргументы представлению. Надеюсь, это кому-нибудь поможет. Вы можете заменить любой тип аргумента или значение для ваших нужд:

Я добавил контекстные фильтры к самому представлению (из набора полей параметров предварительного просмотра). Первый - это «контент: имеет идентификатор термина таксономии». Вторым является «content: nid» с установленным флажком «разрешить несколько» и установленным флажком «исключить» (из набора «еще» во всплывающем окне контекстного фильтра).

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

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

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

return $ view-> args [1];

1

В Drupal 8 вы можете использовать, ViewExecutable::setHandler($display_id, $type, $id, $item)чтобы установить фильтр программно.


4
Этот ответ может быть более подробным о том, почему это работает. Часто мне нравится ссылаться и цитировать страницы документации. Это помогло бы узнать больше об API Drupal и найти информацию для себя в будущем.
Мрадклифф,

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 «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.