Eigenes Views-Sortierfeld aus Voting API
am 13.05.2010 - 15:20 Uhr in
Hallo liebe Drupalgemeinde,
habe eine Frage zu Views bzw. Voting API.
Angenommen ich habe mehrere Produkte und möchte sie nach versch. Eigenschaften, mittels fivestars und Voting API, bewertet haben, zb.
Eigenschaft1
Eigenschaft2
Eigenschaft3
Habe 2 Inhaltstypen definiert:
Inhaltstyp 1 : Produkt
Inhaltstyp 2 : Die verschiedenen Eigenschaften, nach denen ein Produkt bewertet werden kann
Wie erhalte ich dann ein Feld in Views, indem ich z.b. nach :
(Eigenschaft1 + Eigenschaft2 + Eigenschaft3) / 3
sortieren kann.
Wie erhalte ich also immer das insgesamt am besten bewertete Produkt.
Nach einzelnen Kategorien zu filtern oder sortieren ist einfach.
Ich glaube ich sollte das vielleicht über computed field in Inhaltstyp2 hinbekommen, aber bin bisher gescheitert.
Ich bin bald am verzweifeln, für eure Hilfe wäre ich dankbar.
- Anmelden oder Registrieren um Kommentare zu schreiben
Hier -
am 13.05.2010 - 19:13 Uhr
Hier - http://das-drupal-magazin.de/bewertungen-views-darstellen - gibts eine kleine Erläuterung zur Lösung deines Problems.
Hallo MD
am 13.05.2010 - 19:35 Uhr
Hallo md,
danke für deinen Beitrag.
Diese Beschreibung bezieht sich aber nur auf ein Vote Tag bzw. zu bewertende Eigenschaft.
Mein Ziel ist es aber den Durchschnitt aller "Vote Tags" für ein Produkt zu bekommen
Ah, sorry - zu schnell
am 13.05.2010 - 20:48 Uhr
Ah, sorry - zu schnell gelesen und geantwortet.
Dafür kannst du in einer View kein Feld zur Verfügung stellen. Es gibt zwar bei einer View die Option "Rewrite the output of this field". Da kann man sich über "Replacement pattern" die Werte aus anderen Feldern holen. Ich wüsste allerdings nicht, wie man dann danach sortieren könnte.
Hier - http://blog.attomsoft.com/drupal/108/multiple-axis-voting-system-using-d... - findest du aber vielleicht was du suchst.
Ah, sorry - zu schnell
am 14.05.2010 - 01:41 Uhr
Hey md abermals danke,
aber diese Art der Vorgehensweise funktioniert leider nur, wenn man einen einmaligen Vote auf das Produkt macht.
Jeder weitere Vote überschreibt den Alten.
Ich denke ich müsste mit Hilfe von Voting API über das Computed Field diesem Computed Field vorgaukeln es sei ein
Fivestar Field.
Leider habe ich keine Ahnung, wie ich das bewerkstelligen kann, oder ob ich schon wieder auf dem falschen Weg bin.
Also ich bin gespannt und offen für weitere Vorschläge.
Noch eine Idee
am 14.05.2010 - 15:26 Uhr
Hat vielleicht noch jmd. eine Idee zu meinem Problem
Idee
am 31.05.2010 - 09:29 Uhr
Hallo Dennis,
ich hatte das Problem auch und habe es so gelöst, dass ich die eine Bewertungs-Node erstellt habe. Genauer gesagt ist es eine Art Testbericht mit angehänget Bewertung. Dort gibt es 3 Felder für jeweils unterschiedliche Skalen.
In hook_nodeapi() erstelle ich manuell über die VotingAPI die Results und lege eine vierte Dimension für den Durchschnittswert an (kannst du hier berechnen). Damit erhalte ich also einen Voting-Tag, nach dem ich sortieren kann, ohne bei jeder Abfrage die Ergebnisse berechnen zu müssen. Das ganze erfordert jedoch etwas Einarbeitung in die VotingAPI, da man alle Einträge (auch in der Caching Tabelle) selber erstellen muss.
Ich hoffe, das hilft dir weiter!
Viele Grüße
Jan
Codeschnipsel
am 31.05.2010 - 09:37 Uhr
<?php
function eb_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)
{
if($node->type == "testbericht")
{
if($op == "presave")
{
$wertungDimension1 = (100/5*$node->field_wertung1[0]['value']);
$wertungDimension2 = (100/5*$node->field_wertung2[0]['value']);
$wertungDimension3 = (100/5*$node->field_wertung3[0]['value']);
$voteDimension1['content_type'] = "node";
$voteDimension1['content_id'] = $node->field_reference[0]['nid'];
$voteDimension1['value_type'] = "percent";
$voteDimension1['value'] = $wertungDimension1;
$voteDimension1['tag'] = "dimension1";
$voteDimension2['content_type'] = "node";
$voteDimension2['content_id'] = $node->field_reference[0]['nid'];
$voteDimension2['value_type'] = "percent";
$voteDimension2['value'] = $wertungDimension2;
$voteDimension2['tag'] = "dimension2";
$voteDimension3['content_type'] = "node";
$voteDimension3['content_id'] = $node->field_reference[0]['nid'];
$voteDimension3['value_type'] = "percent";
$voteDimension3['value'] = $wertungDimension3;
$voteDimension3['tag'] = "dimension3";
$voteTotal['content_type'] = "node";
$voteTotal['content_id'] = $node->field_reference[0]['nid'];
$voteTotal['value_type'] = "percent";
$voteTotal['value'] = ($wertungDimension1+$wertungDimension2+$wertungDimension3)/3;
$voteTotal['tag'] = "dimensiontotal";
$votes = array($voteDimension1, $voteDimension2, $voteDimension3, $voteTotal);
if(isset($GLOBALS['user']))
{
$user = $GLOBALS['user'];
if($user->uid > 0)
{
$touched = votingapi_set_votes($votes);
}
else
{
$touched = votingapi_set_votes($votes);
}
}
}
if($op == "delete")
{
$criteriaVotes = array();
$criteriaVotes['content_id'] = $node->field_reference[0]['nid'];
$criteriaVotes['content_type'] = "node";
$criteriaVotes['uid'] = $node->uid;
$votes = votingapi_select_votes($criteriaVotes);
$results = votingapi_select_results($votes);
votingapi_delete_votes($votes);
votingapi_delete_results($results);
drupal_set_message("Votes gelöscht!", "status");
}
}
}
?>
Hallo Jan
am 11.06.2010 - 03:31 Uhr
Hallo Jan,
das sieht genau nachdem aus was ich brauche, allerdings bin ich noch nicht ganz so Drupal / PHP versiert.
Darum hätte ich 3 Fragen an dich:
1.Warum machst du das hier: 100/5*$node->field_wertung1...?
2.Was macht diese Auswertung; Bringt doch immer das gleiche Ergebnis, oder?
.
if(isset($GLOBALS['user']))
{
$user = $GLOBALS['user'];
if($user->uid > 0)
{
$touched = votingapi_set_votes($votes);
}
else
{
$touched = votingapi_set_votes($votes);
}
}
3. Kann da sein, dass du hier ALLE votes auf die ref[nid] löschst?
if($op == "delete")
{
$criteriaVotes = array();
$criteriaVotes['content_id'] = $node->field_reference[0]['nid'];
$criteriaVotes['content_type'] = "node";
$criteriaVotes['uid'] = $node->uid;
$votes = votingapi_select_votes($criteriaVotes);
$results = votingapi_select_results($votes);
votingapi_delete_votes($votes);
votingapi_delete_results($results);
drupal_set_message("Votes gelöscht!", "status");
}
Sonst kann ich alles nachvollziehen.
Vielen Dank schon einmal für deine jetzigen Bemühungen.
Hoffe ich steig dann noch dahinter!
lg dennis
Hallo Dennis, hier mal kurz
am 11.06.2010 - 09:37 Uhr
Hallo Dennis,
hier mal kurz ein paar Erläuterungen:
1) Das mache ich, weil die Bewertung von 1-5 vorgenommen werden kann. Da ich aber als VotingApi Skala "percent" und nicht "points" verwende, muss ich den Wert noch auf Prozent umrechnen. Bewertung von 1 ergibt 20%, Bewertung von 5 ergibt 100%. Eine Bewertung von 0% gibt es nicht, Minimum ist 20% = 1 Punkt. Wie sinnvoll das für dich ist, musst du einfach selber überlegen. Bei Amazon, Ebay usw. muss man jedoch auch immer mind. einen Stern vergeben.
2) Das stimmt, das ist so wie es jetzt ist überflüssig. Da hatte ich noch anderen Code zwischen, der anonyme Stimmen und eingloggte Stimmen unterschiedlich gewichtet. Hatte ich dann aber erstmal gelassen.
Hier wollte ich eher den Weg gehen, die Original-Stimmen so zu belassen, und nur die Cachingtabelle entsprechend zu verändern. Damit verändert man die Ergebnisse nicht dauerhaft und könnte den Berechnungsmodus auch später ändern.
3) Generell sieht das so aus: Ich lösche alle Voting-Datensätze zu a) dieser Node-ID, b) vom Typ "node", die c) von User mit uid angelegt worden sind. Da man auch Kommentare und User bewerten kann, heißt das hier content_id und cotnent_type ist daher erforderlich.
Die Eingrenzugn auf UID ist hier wichtig, da der Testbericht gelöscht wird, welcher von einem User angelegt wurde. Nicht verwechseln, es wird hier nicht das Produkt gelöscht, sondern nur der Testbericht. Die Votingstimmen sind mit der Ref-ID zwar dem Produkt zugeordnet, die UID bezieht sich jedoch auf den verfassten Testbericht. Andernfalls würde ich bei Löschen eines Testberichtes, wenn ich keine UID angebe, alle Bewertungen des Produktes löschen.
Wichtig: Das ist auch nur so möglich, da ein User ein Produkt nur einmal bewerten kann. Ein weiterer Testbericht würde die bisherigen Votings überschreiben! Daher musst du noch drauf achte, dass ein Testbericht zu einem Produkt von einem User nur einmal angelegt werden kann und dies entsprechend abfragen. Das ist auch leider eine Einschränkung der Voting API, aber irgendwie natürlich auch sinnvoll. Jede content_id kann von einem User in einer Voting Kategorie (Tag) nur einmal bewertet werden. Für meinen Zweck passte es.
Ich hoffe, das macht es alles klarer.
Hallo Jan
am 11.06.2010 - 23:21 Uhr
Hallo Jan,
vielen, vielen Dank für diese sehr ausführliche, und vor allem schnelle Antwort.
Ich glaube hier bedarf es keiner weiteren Erläuterung deinerseits.
Jetzt erschließt sich selbst mir dieser Algorithmus.
Ganz liebe Grüße
Dennis