Agregue CRITERIOS DE FILTRO en vistas mediante programación


18

Quiero agregar / modificar un filter criteriaprogramáticamente.

Por ejemplo, para una vista, agregué un filtro de "Dirección de correo electrónico" cuyo valor es necesario para cambiar dinámicamente, es necesario establecerlo en la identificación de correo electrónico del usuario conectado actualmente.

¿Cómo lograr eso? Por favor vea la imagen adjunta para más detalles. Por favor ayuda.

ingrese la descripción de la imagen aquí

Respuestas:


24

Use el módulo Develdpm($view) y dpm($query)luego coloque como "test@email.com" en el campo "valor" que se encuentra en su imagen. Vea la estructura de objeto / matriz de la vista y consulte desde la salida de desarrollo.

Luego use la función hook_views_query_alter(&$view, &$query)en su módulo para apuntar a la condición de filtro de condición WHERE y configúrela al valor que desee.

Algo como:

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

¡Muchas gracias! ¿Puedes decirme dónde escribo primero dpm($view);?
Shafiul

crea un módulo personalizado y coloca la función anterior en él. el gancho se disparará si las vistas están habilitadas y verá la consulta $ view y $ en la parte superior de la página una vez que haya habilitado el módulo personalizado y el módulo Devel. Luego simplemente cambie mi código para que el nombre de la máquina de su vista
aparezca

Esa es una gran respuesta. En Drupal 7 usted realmente hace: $ query-> where [1] ['condiciones'] [2] ['value'] = $ user-> email
Artur Kędzior

Personalmente, creo que la respuesta usando los ganchos a continuación es mucho mejor drupal.stackexchange.com/a/200870/9634
kbrinner

6

Aquí hay una alternativa:

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

Sé que probablemente deberías configurar esto usando algún método esotérico y complicado, pero si solo quieres un acceso rápido y sucio sin perder el tiempo, esto te llevará allí.


5

Sería preferible alterarlos en ganchos en lugar de en el momento del renderizado para no socavar el rendimiento del sitio y el almacenamiento en caché. Me llevó edad descubrir que hook_views_pre_build () se dispara demasiado tarde, necesitas hook_views_pre_view () .

Encontré referencia al uso de $ view-> add_item () pero luché por ejemplos, a continuación fue mi solución para filtrar un conjunto de términos de taxonomía para incluir solo ciertos vocabulario:

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

Nota de edición : este comentario en do group me ayudó a descubrir cómo usar los filtros de vistas $view->display_handler->get_option('filters')y luego anularlos usando $view->display_handler->override_option('filters', $filters);.


2

He tenido un problema similar, pero al tratar de pasar varios argumentos a un filtro. He usado el método "views_get_view", pero pasando argumentos a la vista. Espero que esto ayude a alguien. Puede sustituir cualquier tipo de argumento o valor para sus necesidades:

He agregado filtros contextuales a la vista en sí (del conjunto de campos de configuración de vista avanzada). El primero es un "contenido: tiene ID de término de taxonomía". El segundo es "contenido: nid" con la casilla de verificación "permitir múltiples" marcada y "excluir" marcada (desde el conjunto de campos 'más' en la ventana emergente de filtro contextual).

args [] = '1'; // ID de término
args [] = '1 + 2 + 3'; // ID de nodo para excluir / incluir

$ view = views_get_view ($ view_name);
$ vista-> init ();
$ view-> set_display ($ display);
$ view-> set_arguments ($ args);
$ vista-> ejecutar ();
$ vista-> resultado

Actualización: Olvidé mencionar, dentro de los valores del filtro contextual, es posible que deba seleccionar el código php y devolver los argumentos de vista pasados. Por ejemplo:

devuelve $ view-> args [1];

1

En Drupal 8 puede usar ViewExecutable::setHandler($display_id, $type, $id, $item)para configurar un filtro mediante programación.


44
Esta respuesta podría ser un poco más detallada sobre por qué esto funciona. A menudo me gusta vincular y citar las páginas de documentación. Esto ayudaría al autor de la pregunta a aprender más sobre la API de Drupal y a encontrar información por sí mismo en el futuro.
mradcliffe

1

Aquí hay un ejemplo de cómo los criterios de filtro se pueden agregar mediante programación en 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(), '=');
  }
}

La consulta anterior agregará un criterio que filtra los nodos donde el field_custom_criteriacampo es igual al idioma seleccionado actualmente.

Se puede encontrar más información en los documentos: hook_views_query_alter


0

Basado en la respuesta anterior de @ Duncanmoo que sentí que era la mejor, agregué los siguientes filtros a mi punto de vista: pensé que estos serían ejemplos útiles en caso de que no intentara filtrar en función de una taxonomía referenciada, sino de una entidad referenciada o un 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
        )
      );
    }
  }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.