Получите идентификатор узла для всех результатов текущего представления, включая его фильтры, без учета пейджера


У меня есть представление, которое выдает, скажем, 70 результатов с применением определенных открытых фильтров (это представление, в котором используется индексированный контент Apache Solr), и я хочу получить NID каждого результата, чтобы затем я мог отправить его на другую страницу в простом массиве NID.

Я обнаружил, что все идентификаторы NID результатов находятся в массиве $results, созданном представлениями, но в нем есть только результаты, показанные на текущей странице, есть ли способ получить все результаты без учета пейджер, не удаляя его полностью. Невозможно ли это сделать без создания нового запроса на основе активных фильтров? это то, чего я пытаюсь избежать, потому что существует довольно много фильтров.

 4
Author: Daniel Waters, 2014-03-19

2 answers

Вам придется выполнить другой запрос. Нет никакого способа обойти это. Однако вам не нужно использовать представления для второго запроса. Если вам нужен только список NID, EntityFieldQuery идеально подходит.

$query = new EntityFieldQuery();

$query->entityCondition('entity_type', 'node')
 // Add whatever filters your user has set. For example...
  ->entityCondition('bundle', 'mynodetype') // Filter by type
  ->propertyCondition('status', 1) // filter by published/unpublished status
  ->fieldCondition('field_foo', 'value', 'bar', '=') // filter by the value of a field
// Order however you want, for example...
  ->fieldOrderBy('field_foo', 'fid', 'DESC') // Order by a field value
// Set the range to get the number you want to see.
  ->range(0, 70)

$result = $query->execute();
$nids = array_keys($result['node']);

Это даст вам только список nid, более быстрый и эффективный, чем выполнение целого отдельного запроса, такого как запрос, сгенерированный представлением.

 1
Author: beth, 2014-03-19 18:15:26

Я столкнулся с этой проблемой в недавнем проекте. Я решил отказаться от решения EntityFieldQuery или db_query()/db_select() по четырем причинам.

  1. Представления могут делать некоторые действительно странные вещи, когда они строят запрос. Например, в некоторых случаях при добавлении сортировки ключ сортировки будет добавлен в список возвращаемых полей . Это может изменить то, что возвращается при включении агрегации, уменьшении количества дубликатов и т. Д.

  2. Представления, как правило, используют LEFT JOIN вместо INNER JOIN. Вы можете сделать это с db_query() и db_select(), но не EntityFieldQuery.

  3. SQL может быть непредсказуемым с неопределенным порядком между наличием LIMIT или нет. Например, если вы сортируете по названиям и у вас есть дубликаты, я видел разные порядки результатов. Это означает, что вам, возможно, потребуется быть действительно четким с сортировками, если важен порядок (я реализовывал prev/next через результирующий набор, так оно и было).

  4. Мне действительно не нравится реализовывать что-то в коде, когда я знаю некодер может захотеть настроить представление.

Итак, я закончил тем, что использовал это:

$all = views_get_view('my_view');

$all->display['default']->display_options['pager'] = array(
  'type' => 'none',
  'options' => array(
    'offset' => 0,
  ),
);

$all->set_display('my_display');

$all->display[$all->current_display]->display_options['pager'] = array(
  'type' => 'none',
  'options' => array(
    'offset' => 0,
  ),
);

$all->pre_execute();
$all->execute();

$nids = array();

foreach ($all->result as $result) {
  $nids[] = (int) $result->nid;
}

Это будет

  • Вручную создайте экземпляр представления.
  • Сбросьте пейджер на главном устройстве, чтобы отобразить все результаты, начиная с 0.
  • Установите дисплей на то, что я использую.
  • Сбросьте и этот пейджер.
  • Выполнить представление
  • Просмотрите результаты для того, что мне нужно.
 3
Author: mpdonadio, 2017-04-13 12:47:02