Как я могу изменить значение фильтра и изменить выходные данные перед отображением представления?

15

При использовании Drupal 7 и Views 3, как правильно изменить значение фильтра Views, чтобы оно влияло на содержимое, которое только что будет визуализировано?

Я перепробовал все упомянутое здесь для D6.

Хотя несколько человек заставили его работать, Мерлин утверждает, что изменение display_options - неправильный способ достижения этого, но он расплывчат в своем ответе относительно того, что делать ( http://drupal.org/node/789710#comment- 2927556 ).

Я пытался:

function pages_views_pre_view($view){
    $view = views_get_view('north_carolina');
    $view->set_display('default');

    $view->display_handler->options['filters']['province']['value'] = 'Georgia';
    dsm($view->display_handler->options['filters']['province']);
}

Примечания:

1) У меня есть созданное north_carolinaпредставление с двумя типами отображения - страница и блок (page_1 и block_1).

2) мои фильтры одинаковы для всех моих дисплеев, поэтому я пытаюсь изменить отображение по умолчанию, чтобы оно влияло на все из них.

3) Значением по умолчанию для моего фильтра является «Северная Каролина» (которое я установил в пользовательском интерфейсе Views), но обратите внимание, что я пытаюсь изменить его на «Georgia»

4) Если я запускаю DSM сразу после этого, я вижу, что фильтр был изменен, однако мои результаты по-прежнему показывают результаты «Северная Каролина». Кэширование отключено, и я все еще получаю то же самое после запуска drush cc all.

Я также попытался запустить тот же код через hook_views_pre_buildи hook_views_pre_execute.

Какие-либо предложения?

РЕДАКТИРОВАТЬ:

Как предполагается, это может помочь получить дополнительную информацию. Вот дамп вида:

$view = new view();
$view->name = 'north_carolina';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'North Carolina';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'test nc block';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Location: Province */
$handler->display->display_options['filters']['province']['id'] = 'province';
$handler->display->display_options['filters']['province']['table'] = 'location';
$handler->display->display_options['filters']['province']['field'] = 'province';
$handler->display->display_options['filters']['province']['value'] = 'North Carolina';
$handler->display->display_options['filters']['province']['exposed'] = TRUE;
$handler->display->display_options['filters']['province']['expose']['operator_id'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['label'] = 'State';
$handler->display->display_options['filters']['province']['expose']['operator'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['identifier'] = 'province';
$handler->display->display_options['filters']['province']['expose']['remember_roles'] = array(
  2 => '2',
  1 => 0,
  3 => 0,
  4 => 0,
);

/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block_1');
$handler->display->display_options['block_description'] = 'test nc block';

Обратите внимание, что эти обработчики предоставляются модулем location. Специально для фильтра "Местоположение: провинция" мне предоставляется форма автозаполнения. Когда я печатаю в Северной Каролине, он появляется, и я должен выбрать это. Тем не менее, обратите внимание, что в операторе SQL, который генерирует представления, используется двухбуквенное сокращение для состояния:

SELECT node.title AS node_title, node.nid AS nid, node.created AS node_created
FROM 
{node} node
LEFT JOIN {location_instance} location_instance ON node.vid = location_instance.vid
LEFT JOIN {location} location ON location_instance.lid = location.lid
WHERE (( (node.status = '1') AND (location.province = 'NC') ))
ORDER BY node_created DESC
LIMIT 10 OFFSET 0
blue928
источник

Ответы:

8

Может быть сложно определить точную часть объекта представлений для изменения. Обычно я сначала экспортирую представление и смотрю на сгенерированный код, чтобы начать работу.

Приведенный ниже фрагмент не изменен и работает, как и ожидалось, на одном из моих производственных сайтов. Надеюсь, этого достаточно, чтобы вы пошли в правильном направлении (очевидно, это в пользовательском модуле с именем offer_select). Если вы можете предоставить код из экспортированного представления, кто-то может взглянуть.

//Alter the End date filter on the offer views
function offer_select_views_pre_view(&$view) {
  if ($view->name == 'active_offers') {
    $view->display['default']->handler->options['filters']['field_end_value']['value']['value'] = time();
  }
}

- ОБНОВЛЕНИЕ--
Для вашего конкретного вида я установил модуль Location и создал несколько узлов в NC и несколько в Грузии и импортировал ваше представление для тестирования. В моем собственном модуле (названном dev) я начал с этого кода (с установленной devel):

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']);
  }
}

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

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']['province']['value']);
  }
}

Который просто напечатан North Carolinaна Крумо. В этот момент я изменил значение для печати на следующее:

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    $view->display['default']->handler->options['filters']['province']['value'] = 'Georgia';
  }
}

И вуаля. Это добилось цели.

Адам Бальзам
источник
Здорово. Когда у меня будет возможность, я поиграю с твоим мнением и посмотрю, смогу ли я найти более конкретный ответ.
Адам Бальзам
@ blue928 см. выше. Я обновил свой ответ ответом на ваши вопросы и общими инструкциями о том, как я туда попал.
Адам Бальзам
это работало отлично. Примечание о правильном ответе. Часть моей проблемы заключается в том, что мне не нужно вызывать views_get_view или устанавливать отображение.
blue928
2

На случай, если у кого-то возникнет эта тема во время поиска того же решения на D8 (как я сделал):

Новый API позволяет манипулировать этими параметрами более понятным способом. Смотрите этот раздел для справок.

Маленький пример

function dev_views_pre_view(ViewExecutable &$view, $display_id, array &$args) {
  if ($display_id === 'my_unique_display_name') {
      $args[0] = 'desired_value';
  }
}
Der Zinger
источник