Wie "zwinge" ich VIEWS als Operator "IN" anstelle von "LIKE" im Query zu verwenden?
am 26.09.2008 - 10:06 Uhr in
Hallo liebe Drupalgemeinde,
ich bin nun schon eine ganze Weile mit diesem Problem zugange,
vielleicht habe ich ja Glück, und Views- Experten lesen diese
Zeilen.
Es geht um eine View, welche unterhalb eines Node als Block eingebunden wird.
Jeder dieser Nodes kommt mit einer Postleitzahl.
Die View soll nun dynamisch, abhängig von der Postleitzahl des Nodes generiert werden.
Konkret soll die View andere Nodes mit Postleitzahl innerhalb eines festen Umkreises
ausgeben. Eine Umkreisfunktion welche die entsprechenden Postleitzahlen ausgibt existiert.
Ich habe die View (mit dem User- Interface) soweit erstellt,
und versucht, über das "Views argument handling" die gewünschte Funktionalität herzstellen - leider ohne den gewünschten Effekt. Ich habe es über das argument handling nicht geschafft, den VIEW-Operator so zu modifizieren, dass Sie den gewünschten Query generiert.
Diesen Query konnte ich mit dem argument Handling erzeugen:
node_data_field_postleitzahl.field_postleitzahl_value LIKE ('zip1','zip2'...)
Und diesen hätte ich gebraucht:
...node_data_field_postleitzahl.field_postleitzahl_value IN ('zip1','zip2'...)....
Habe ich den falschen Ansatz gewählt? Gibt es eine einfachere Möglichkeit,
die gewünschte Funktionalität zu erreichen?
Ansonsten müsste ich die View als Modul? ausprogrammieren und meinen
gewünschten query selber setzen?
Für Anregungen und Denkanstöße wäre ich sehr dankbar.
Besten Gruss
Markus
- Anmelden oder Registrieren um Kommentare zu schreiben
Schreibe einen neuen Filter
am 26.09.2008 - 11:16 Uhr
--
Hallo Traxer,
am 26.09.2008 - 13:05 Uhr
Hallo Traxer,
vielen vielen Dank für deine Antwort.
Es geht um Views 1.x.
Sehe ich das richtig, dass ich diesen Filter dann in dem User- Interface unter "Filter"
der bestehenden View auswählen könnte?
Wird der Code als Module eingebunden?
Hier ist ein erster Entwurf, bin mir leider nicht im Klaren wie das Gerüst
für den Filter/ aussieht:
<?php
.
.
.
// Postleitzahl des Nodes
$zip = $node->field_postleitzahl[0]['value'];
// @return an array of nearby postal codes within 50 KM
$nearby = get_nearby_postal_codes ( $zip, 50 );
// hier fehlt sicher noch was?
// Filter für field_postleitzahl deklarieren
$table = array(
'filters' => array(
'field_postleitzahl' => array(
'name' => t('Umkreisfilter'),
'help' => t('Filtert Nodes nach Postleitzahl in einem Umkreis'),
'field' => 'field_postleitzahl',
'operator' => array('IN'),
'value' => $zip,
'value-type' => 'array',
// Sollte doch ohne Handler funktionieren?
),
),
);
// hier fehlt sicher noch was?
?>
Re: Hallo Traxer,
am 26.09.2008 - 13:38 Uhr
Sehe ich das richtig, dass ich diesen Filter dann in dem User- Interface unter "Filter" der bestehenden View auswählen könnte?
Ja.
Wird der Code als Module eingebunden?
Ja. Das heißt du schreibst eine Datei
mymodule.module
mit einer Funktion<?php
function mymodule_views_tables() {
// Tabellen- und Filterdefinitionen
}
?>
Außerdem brauchst du noch eine Datei
mymodule.info
.Hier ist ein erster Entwurf, ...
Ist schon mal ein Anfang. Allerdings wirst du wohl doch einen Handler benötigen.
hook_views_tables
wird nämlich bei der Definition des Views ausgeführt. Also zu einem Zeitpunkt, zu dem du noch nicht weißt, welchen Wert der Benutzer als Postleitzahl eingegeben hat.Der Handler wird dagegen bei der Ausführung des Views ausgeführt. Erst jetzt weißt du welchen Wert der Benutzer eingegeben hat.
--
Hallo Traxer,
am 30.09.2008 - 11:04 Uhr
vielen Dank für deinen fachkundigen Rat.
Ich denke, ich nähere mich dem gewünschten Ergebnis,
allerdings schaffe ich es bisher nicht, dass die View meinen "Umkreisfilter"
unter "Filter" auch aufführt - so dass ich diesen Filter dann zumindest schonmal auswählen könnte.
Das Modul ist geschrieben und aktiviert - ist auch nicht mein erstes Modul.
Habe dann zunächst einen ganz einfachen Filter + Handler geschrieben,
welcher zu Testzwecken bewusst noch nicht die gewünschte Funktionalität besitzt.
Aber leider wird dieser nicht als verfügbarer Filter angezeigt.
Woran könnte Views sich stören bzw. mache ich einen Denkfehler?
Das Modul:
<?php
// $Id: views_nearby_filter.module$
function views_nearby_filter_views_tables() {
// Filter für field_postleitzahl deklarieren
$table = array(
'filters' => array(
'field_postleitzahl' => array(
'name' => t('Umkreisfilter'),
'help' => t('Filtert Nodes nach Postleitzahl in einem Umkreis'),
'operator' => 'views_handler_operator_gtlt',
'value' => array(
'#type' => 'textfield', // Im query wird hier ein array eingesetzt
'#size' => 5,
),
'handler' => 'views_nearby_filter_views_handler_filter_zip',
),
),
);
}
/**
* Views filter handler: zip filter.
*/
function views_nearby_filter_views_handler_filter_zip($op, $filter_data, $filter_info, &$query) {
$zip = ('50321');
$table = $filter_info['table'];
$table_field = $filter_info['content_db_info']['columns']['field_postleitzahl']['column'];
$operator = $filter_data['operator'];
$query->add_table($table);
$query->add_where("$table.$table_field $operator ('". $zip ."')");
}
?>
Eine andere Möglichkeit wäre doch auch über
hook_views_query_alter(&$query, &$view, $summary, $level)
zu gehen und den Query zu erweitern bzw. anzupassen?
Halte ersteres Vorgehen aber für sauberer.
Besten Gruß
Markus
return $table
am 01.10.2008 - 09:40 Uhr
Wenn ich jetzt sage: "
return $table;
", dann weißt du bestimmt wo diese Zeile fehlt :-)Außerdem:
Die View soll nun dynamisch, abhängig von der Postleitzahl des Nodes generiert werden.
<?php
/**
* Views filter handler: zip filter.
*/
function views_nearby_filter_views_handler_filter_zip($op, $filter_data, $filter_info, &$query) {
if (arg(0) != 'node' || !is_numeric(arg(1))) {
return; // Wenn ich nicht auf einer node-Seite bin, dann wird nicht weiter gefiltert.
}
$nid = arg(1);
$node = node_load($nid);
if ($node) {
$zip = $node->field_postleitzahl[0]['value'];
$nearby = get_nearby_postal_codes ( $zip, 50 );
$table = $filter_info['table'];
$table_field = $filter_info['content_db_info']['columns']['field_postleitzahl']['column'];
$operator = $filter_data['operator'];
$query->add_table($table);
$query->add_where("$table.$table_field $operator (". join(',', $nearby) .")");
}
}
?>
Der Block sollte so konfiguriert werden, das er nur auf node-Seiten angezeigt wird. Dann ist
arg(1)
die $nid des Nodes der angezeigt wird. Aus diesem Node extrahierst du die Postleitzahl und fütterst sie an deine Funktion zur Umkreissuche. Das Textfeld, das du zur Koniguration zu Verfügung hast, kannst du dann für die Entfernung verwenden (so das du nicht auf 50km festgelegt bist).--
Aua, peinlich peinlich...ja
am 09.10.2008 - 09:34 Uhr
Aua, peinlich peinlich...ja ich sollte eigentlich wissen an welche Stelle das "return" gehört ;-)
Deine Lösung läuft jetzt einfach perfekt. Vielen vielen Dank für die super Unterstützung!
Besten Gruß
Markus