it-swarm.com.de

Fügen Sie programmgesteuert FILTERKRITERIEN in Ansichten hinzu

Ich möchte programmgesteuert einen filter criteria Hinzufügen/ändern.

Für eine Ansicht habe ich beispielsweise einen Filter "E-Mail-Adresse" hinzugefügt, dessen Wert sich dynamisch ändern muss. Er muss auf die aktuell angemeldete E-Mail-ID des Benutzers festgelegt werden.

Wie erreicht man das? Weitere Details finden Sie im beigefügten Bild. Bitte helfen Sie.

enter image description here

18
Shafiul

Verwenden Sie das Modul Devel und dpm($view) und dpm($query), nachdem Sie "[email protected]" in das Feld "value" in Ihrem Bild eingegeben haben. Siehe die Objekt-/Array-Struktur der Ansicht und Abfrage aus der Entwicklungsausgabe.

Verwenden Sie dann die Funktion hook_views_query_alter(&$view, &$query) in Ihrem Modul, um auf die WHERE-Bedingungsfilterbedingung abzuzielen und sie auf den gewünschten Wert zu setzen.

Etwas wie:

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
    // '[email protected]' 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;
  }
}
25
tenken

Hier ist eine Alternative:

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

Ich weiß, dass Sie dies wahrscheinlich mit einer esoterischen, verschlungenen Methode einstellen sollten, aber wenn Sie nur einen schnellen und schmutzigen Zugriff wünschen, ohne herumzuspielen, werden Sie dorthin gelangen.

7
rix

Es ist vorzuziehen, diese in Hooks anstatt zum Rendern zu ändern, damit Sie die Leistung und das Caching der Site nicht beeinträchtigen. Ich brauchte Alter, um herauszufinden, dass hook_views_pre_build () zu spät ausgelöst wird, Sie benötigen hook_views_pre_view () .

Ich fand einen Verweis auf die Verwendung von $ view-> add_item () , kämpfte jedoch um Beispiele. Nachfolgend war meine Lösung zum Filtern einer Reihe von Taxonomiebegriffen aufgeführt, um nur bestimmte Vokabeln einzuschließen:

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

Notiz bearbeiten : Dieser Kommentar on do group hat mir geholfen herauszufinden, wie ich die Ansichtsfilter mit $view->display_handler->get_option('filters') erhalte. und um sie dann mit $view->display_handler->override_option('filters', $filters); zu überschreiben.

6
Duncanmoo

Ich hatte ein ähnliches Problem, aber ich habe versucht, mehrere Argumente an einen Filter zu übergeben. Ich habe die Methode "views_get_view" verwendet, aber Argumente an die Ansicht übergeben. Ich hoffe es hilft jemandem. Sie können Ihre Anforderungen durch einen beliebigen Argumenttyp oder -wert ersetzen:

Ich habe der Ansicht selbst Kontextfilter hinzugefügt (aus dem Feldsatz für die erweiterten Ansichtseinstellungen). Der erste ist ein "Inhalt: hat Taxonomie-Begriff ID". Die zweite Option ist "content: nid", wobei das Kontrollkästchen "mehrere zulassen" aktiviert und das Kontrollkästchen "ausschließen" aktiviert ist (aus dem Feldsatz "Mehr" im Kontextfilter-Popup).

 Args [] = '1'; // Term ID 
 Args [] = '1 + 2 + 3'; // Node IDs zum Ausschließen/Einschließen von 
 
 $ View = views_get_view ($ view_name); 
 $ View-> init (); 
 $ view-> set_display ($ display); 
 $ view-> set_arguments ($ args); 
 $ view-> execute (); 
 $ view- > Ergebnis 

Update: Ich habe vergessen zu erwähnen, dass Sie innerhalb der kontextbezogenen Filterwerte möglicherweise PHP-Code auswählen und die übergebenen Ansichtsargumente zurückgeben müssen. Beispiel:

 return $ view-> args [1]; 
3
Seb

In Drupal 8) können Sie mit ViewExecutable::setHandler($display_id, $type, $id, $item) einen Filter programmgesteuert einstellen.

2
vlledo

Hier ist ein Beispiel, wie Filterkriterien programmgesteuert in 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(), '=');
  }
}

Die obige Abfrage fügt ein Kriterium hinzu, das Knoten filtert, bei denen field_custom_criteria Feld entspricht der aktuell ausgewählten Sprache.

Weitere Informationen finden Sie in den Dokumenten: hook_views_query_alter

1
estrar

Basierend auf @ Duncanmoo 's Antwort oben , die ich für am besten hielt, fügte ich meiner Ansicht die folgenden Filter hinzu - dachte, dies wären nützliche Beispiele, falls Sie es nicht versuchen würden Filtern basierend auf einer referenzierten Taxonomie, aber stattdessen auf einer referenzierten Entität oder einer 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
        )
      );
    }
  }
}
1
kbrinner