Fügen Sie FILTER CRITERIA in Views programmgesteuert hinzu

18

Ich möchte ein filter criteriaprogrammgesteuert hinzufügen / ändern .

Beispielsweise habe ich für eine Ansicht einen Filter "E-Mail-Adresse" hinzugefügt, dessen Wert sich dynamisch ändern muss. Er muss auf die aktuelle E-Mail-ID des angemeldeten Benutzers eingestellt werden.

Wie kann man das erreichen? Bitte beachten Sie das beigefügte Bild für weitere Details. Bitte helfen Sie.

Bildbeschreibung hier eingeben

Shafiul
quelle

Antworten:

24

Verwenden Sie das Devel - Modul und dpm($view)und dpm($query)nachdem Sie setzen wie „[email protected]“ in das Feld „Wert“ gefunden in Ihrem Bild. 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 die WHERE-Bedingungsfilterbedingung als Ziel festzulegen und auf den gewünschten Wert festzulegen.

So 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;
  }
}
tenken
quelle
Danke vielmals! Können Sie mir bitte sagen, wo ich zuerst schreiben soll dpm($view);?
Shafiul,
Sie erstellen ein benutzerdefiniertes Modul und platzieren die obige Funktion darin. Der Hook wird ausgelöst, wenn Ansichten aktiviert sind. Sobald Sie das benutzerdefinierte Modul und das Entwicklermodul aktiviert haben, wird oben auf der Seite $ view und $ query angezeigt. Dann ändere einfach meinen Code, damit der Computername deiner Ansicht darin steht ... und die $ query-Werte mit deiner genauen Abfrage
funktionieren
Das ist eine großartige Antwort. In Drupal 7 machen Sie tatsächlich: $ query-> where [1] ['conditions'] [2] ['value'] = $ user-> email
Artur Kędzior
Persönlich denke ich, dass die Antwort unter Verwendung der Haken unten viel besser ist. Drupal.stackexchange.com/a/200870/9634
kbrinner
6

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, gelangen Sie dorthin.

rix
quelle
5

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

Ich habe einen Verweis auf die Verwendung von $ view-> add_item () gefunden, hatte aber Probleme mit Beispielen. Unten war meine Lösung zum Filtern einer Reihe von Taxonomiebegriffen, 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);
    }
  }
}

Anmerkung bearbeiten : Dieser Kommentar zu do group hat mir geholfen, herauszufinden, wie ich die Ansichtsfilter verwenden $view->display_handler->get_option('filters')und sie dann mithilfe von überschreiben kann $view->display_handler->override_option('filters', $filters);.

Duncanmoo
quelle
2

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 jeden Argumenttyp oder Wert für Ihre Anforderungen einsetzen:

Ich habe der Ansicht selbst Kontextfilter hinzugefügt (aus dem Feldset Erweiterte Ansichtseinstellungen). Der erste ist ein "Inhalt: hat Taxonomiebegriff ID". Das zweite Feld ist "content: nid" mit aktiviertem Kontrollkästchen "mehrere zulassen" und "ausschließen" (aus dem Feld "more" im Kontextfilter-Popup).

args [] = '1'; // Term ID
args [] = '1 + 2 + 3'; // Knoten-IDs zum Ausschließen / Einschließen

$ view = views_get_view ($ view_name);
$ view-> init ();
$ view-> set_display ($ display);
$ view-> set_arguments ($ args);
$ view-> execute ();
$ view-> result

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

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

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

vlledo
quelle
4
Diese Antwort könnte etwas ausführlicher darüber sein, warum dies funktioniert. Oft möchte ich die Dokumentationsseiten verlinken und zitieren. Dies würde dem Fragesteller helfen, mehr über die Drupal-API zu erfahren und in Zukunft Informationen für sich selbst zu finden.
Mradcliffe
1

Hier ist ein Beispiel, wie Filterkriterien in Drupal 8 programmgesteuert hinzugefügt werden können:

/**
 * @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 das field_custom_criteriaFeld der aktuell ausgewählten Sprache entspricht.

Weitere Informationen finden Sie in den Dokumenten: hook_views_query_alter

estrar
quelle
0

Basierend auf der obigen Antwort von @ Duncanmoo , die ich als am besten empfand, fügte ich meiner Ansicht die folgenden Filter hinzu - ich dachte, dies wären nützliche Beispiele, falls Sie nicht nach einer referenzierten Taxonomie filtern wollten, sondern nach einer referenzierten Entität oder eine 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
        )
      );
    }
  }
}
kbrinner
quelle