[Ideenfindung] Sterne-Bewertungsscript PHP/MySQL-DB

godlike

Warp drölf
Veteran
Registriert
13 Juli 2013
Beiträge
14.290
Ort
Topkekistan
Bin gerade am überlegen wie ich das am besten umsetze. Für das Script habe ich jetzt mal folgende Tabelle angelegt

ID | rating | count

Die ID referenziert zum jeweiligen Eintrag. Rating errechnet/addiert sich auch den bereits angeklickten Sternen und count wird am Ende für das aktuelle Rating benötigt (rating / count = Sterne).

Nun überlege ich wie ich das am geschicktesten in PHP und HTML umsetze. Habe momentan ein Konstrukt im Kopf mit mehreren Ebenen und ich bin mir nicht sicher ob das vom Ansatz her schon ziemlich dämlich ist. Ich hätte jetzt als Hintergrundebene eines DIVs o.Ä. eine 5-Sterne Grafik mit leeren Sternen eingebunden. Darüber kommt denn eine zweite Grafik mit gefüllten Sternen. Die Breite dieser zweiten Ebene errechnet sich durch

(rating / count) * 20 = Breite in %

Haben 3 Personen abgestimmt, jeweils mit 5 Sternen, 3 Sternen und 5 Sternen ergibt sich ein insgesamtes rating von 13. Das durch den count von 3 wären 4,3 Sterne (4,3 * 20% = ~87%). Sprich die Grafik mit den Gefüllten Sternen müsste die darunterliegende mit den leeren zu 87% überdecken. Stimmt so oder?

Nur wie mache ich das jetzt mit den anklickbaren einzelnen Sternen? Noch mal 5 Einzelgrafiken mit Sternen darüber legen, die bei mouse-over auf visible setzen und beim hoover noch hervorheben?

Stehe gerade irgendwie auf dem Schlauch.

Sollte ich kompletten Blödsinn denken dürft ihr mir das gerne sagen :D

Viele Grüße

godlike
 
Gibt mehrere Möglichkeiten:

a) Sterne als Einzelgrafiken → Vorteil: einfach. Nachteil: keine Änderung der anderen Sterne bei Hover
b) Grafiken für jede Wertung in 0,5er-Schritten (wie bei Amazon) → Vorteil: geringe Ladezeit bei vielen Besuchern
c) Image Maps → Vorteil: einfach; Nachteil: technisch veraltet
d) unsichtbare DIVs als Overlay und Javascript → Vorteil: sieht vermutlich am Besten aus; Nachteil: Javascript, komplexer
e) ?

Ich würde vermutlich einfach eine Grafik eines vollen Sterns nehmen und den Hintergrund horizontal wiederholen, den dann je nach Wertung . Dann im Vordergrund noch diverse DIVs mit 1,2,3,4,5 Sternen, die dann jeweils 20/40/60/80/100% breit sind. Dadurch lädst du genau eine kleine Sternchengrafik und kannst alles abbilden.
 
@Godlike,

mir fällt spontan bei deiner Berechnung auf das der Fall nicht berücksichtigt das jemand sein Rating ändert?

Dann müsstest du zwar das Rating für jeden aktiven Nutzer speichern und bei Bedarf/Änderung eines Ratings den Gesamtwert für einen Artikel neu berechnen, wäre aber langfristig wohl idealer. Auch kannst du so Benutzer finden die eine Reihe von eventuelle "getaggten" Artikeln bewertet haben und wie hoch, zum Beispiel.
 
mir fällt spontan bei deiner Berechnung auf das der Fall nicht berücksichtigt das jemand sein Rating ändert?

Würde doch folgendermaßen funktionieren: Bei einer Änderung erst die Wertung rückgängig machen (rating minus Userrating, count minus eins) und dann die Bewertung ganz normal wie eine neue hinzufügen. :unknown:
 
... Bei einer Änderung erst die Wertung rückgängig machen...

Richtig, aber in seinem Beispiel speichert Godlike nur die Gesamtwert und Anzahl der Stimmen, nicht jedoch die Wertung die ein User gemacht hat um deine Rechnung durchzuführen, das meinte ich unter anderem mit meinem Post, er müßte dazu wissen ob es vorher 1 oder 5 gewesen ist.
 
  • Thread Starter Thread Starter
  • #6
Danke schon mal für eure Ideen :T

Ja, das mit dem Wertung rückgängig machen ist so eine Sache. Daran hatte ich noch gar nicht gedacht bzw. so weit war ich noch nicht.

Eine zusätzliche Userdatenbank will ich jetzt eigentlich nicht extra anlegen. Vielleicht irgendwas über Sessions? Da könnte ich ja zumindest temporär den count und den dazugehörige value speichern. Wer den Browser zwischendurch schließt hat halt Pech gehabt :coffee: Wobei ich bei einer Reloadsperre ich IP + Zeitstempel eh separat in der DB speichern müsste. Mist :dozey:
 
Rein technisch:

Eine teiltransparente 5-Sterne-Grafik mit leeren Sternen, Rest opak. Darunter (oder je nach HTML-Element, das Du verwenden willst, als background mit position) einfach ein gelbes Rechteck, das je nach Wertung positioniert wird, ob nun prozentual (funktional transparenter) oder in px.

Speicherung der erfolgten Bewertung in window.localStorage, daher auch Änderung möglich. Speicherung aller Einzelbewertungen in einer DB-Tabelle. Identifikation der Bewertungen über einen Timestamp an beiden Speicherorten -> relativ eindeutig, Unschärfe wirds aber immer geben, so lange Du nicht Fingerprinting etc. verwenden willst - was ich hier für *hust* Schwachsinn halte :)

J.

Nachtrag: scheinbar nicht vollständig gelesen/verstanden... die Bewertungssterne zum Anklicken übersehen *grmpf* hier wirds mit MouseOver ohne JS nichts, vorausgesetzt, Dir reicht nicht (Einzelsterne), dass nur der - bei 5 Unterteilungen - jeweilige x20% Stern gehovert wird...
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #8
Update!

Habe nach längeren Überlegungen dann doch zu einem fertigen Script gegriffen. Der Aufwand ist m.M.n. einfach zu groß. Habe mich für entschieden. Läuft einwandfrei, hat alles was es braucht, + Admin Umgebung. Also Kommentare verfassen, Kommentare Bewerten, Kommentare kommentieren, Bilder, Smilies usw. Design hab ich auch easy anpassen können. Alles super.

Nun hab ich aber doch ein Problem festgestellt. Meine Seite läuft über eine DB. Die URL wird aus zwei Variablem der DB zusammengebaut. Nennen wir sie foo und bar. Mit einer ID, die natürlich unique ist, referenziere ich zwischen den einzelnen DB's. Darum nutze ich diese ID auch um die Kommentare zuzuordnen. Klappt alles. Oft getestet.

Das Script wird wie folgt eingebunden:

[src=php]$cmtx_identifier = $zeile['id'];
$cmtx_reference = $zeile['name'];
$cmtx_path = $_SERVER['DOCUMENT_ROOT'].'comments/';
require $cmtx_path.'includes/commentics.php';[/src]

Meine URLs lauten wie folgt:

http://www.domain.de/foo/bar/site

Wobei sich foo und bar natürlich dynamisch aus der DB kommen wie gesagt. Dazu die ID welche ich per $cmtx_identifier dem jeweiligen Kommentar zuweise. $zeile['name'] ist einfach der jeweilige Name der Seite und wird beim Kommentar eingebunden.

Gehe ich nun (bei mehr als 5 Kommentaren) auf die zweite Seite erhalte ich folgenden Link:

http://www.domain.de/foo/bar/site?cmtx_page=2#cmtx_comments

aber es ändert sich nichts. Er zeigt weiterhin die ersten 5 Kommentare an.

Habe ich hier einen Denkfehler? Die Kommentare, sagen wir mal auf Seite http://www.domain.de/blah/blub/site haben alle die ID 18432. Die Referenzierung klappt also wunderbar. Wieso zeigt er mir immer nur die ersten an?

PS: die URL baue ich per RewriteEngine um.

RewriteRule ^(.*)/(.*)/site$ /seiten/infos/details.php?foo=$1&bar=$2 [L]

ergibt

http://www.domain.de/foo/bar/site

Ideen?

Nachtrag: Hab mal die entsprechende function von Commentics heraus gesucht:

[src=php]function cmtx_paginate($current_page, $range_of_pages, $total_pages) { //display pagination

if ($current_page > 1) { //if not on the first page
echo ' <span class="cmtx_pagination_box"><a href="' . cmtx_url_encode(strtok(cmtx_current_page(), '?') . '?cmtx_page=1' . cmtx_get_query('page') . CMTX_ANCHOR_COMMENTS) . '" class="cmtx_pagination_link" title="' . CMTX_TITLE_PAG_FIRST . '">' . CMTX_PAGINATION_FIRST . '</a></span> '; //display link to go to first page
$previous_page = $current_page - 1; //get the previous page number
echo ' <span class="cmtx_pagination_box"><a href="' . cmtx_url_encode(strtok(cmtx_current_page(), '?') . '?cmtx_page=' . $previous_page . cmtx_get_query('page') . CMTX_ANCHOR_COMMENTS) . '" class="cmtx_pagination_link" title="' . CMTX_TITLE_PAG_PREVIOUS . '">' . CMTX_PAGINATION_PREVIOUS . '</a></span> '; //display link to go back one page
}

for ($x = ($current_page - $range_of_pages); $x < (($current_page + $range_of_pages) + 1); $x++) { //loop to display links to range of pages around current page
if (($x > 0) && ($x <= $total_pages)) { //if it's a valid page number
if ($x == $current_page) { //if it's the current page
echo ' <span class="cmtx_pagination_box cmtx_pagination_box_active">' . $x . '</span> '; //display it but don't make it a link
} else { //if it's not the current page
echo ' <span class="cmtx_pagination_box"><a href="' . cmtx_url_encode(strtok(cmtx_current_page(), '?') . '?cmtx_page=' . $x . cmtx_get_query('page') . CMTX_ANCHOR_COMMENTS) . '" class="cmtx_pagination_link" title="' . $x . '">' . $x . '</a></span> '; //display it and make it a link
}
}
}

if ($current_page != $total_pages) { //if not on the last page
$next_page = $current_page + 1; //get the next page number
echo ' <span class="cmtx_pagination_box"><a href="' . cmtx_url_encode(strtok(cmtx_current_page(), '?') . '?cmtx_page=' . $next_page . cmtx_get_query('page') . CMTX_ANCHOR_COMMENTS) . '" class="cmtx_pagination_link" title="' . CMTX_TITLE_PAG_NEXT . '">' . CMTX_PAGINATION_NEXT . '</a></span> '; //display link for next page
echo ' <span class="cmtx_pagination_box"><a href="' . cmtx_url_encode(strtok(cmtx_current_page(), '?') . '?cmtx_page=' . $total_pages . cmtx_get_query('page') . CMTX_ANCHOR_COMMENTS) . '" class="cmtx_pagination_link" title="' . CMTX_TITLE_PAG_LAST . '">' . CMTX_PAGINATION_LAST . '</a></span> '; //display link for last page
}

}[/src]

Ok, hier wird ja von der function cmtx_paginate() auf $current_page und $cmtx_current_page zugegriffen. Zweiteres nutzt $_GET['cmtx_page']

[src=php]if (isset($_GET['cmtx_page']) && ctype_digit($_GET['cmtx_page'])) {
$cmtx_current_page = (int) $_GET['cmtx_page']; //get the current page
} else {
$cmtx_current_page = 1; //or set a default
}[/src]

Ist hier viellelicht der Hund begraben? Ich steig noch nicht soganz durch :dozey:
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #10
Da bekomme ich dann auf allen Seiten, also nicht nur bei der Speziellen RewriteRule, einen Internal Server Error.

Liegt aber devinitiv an der RewriteRule. Versuche ich es über folgenden Aufruf klappt es:

http://www.domain.de/seiten/infos/details.php?foo=blah&bar=blubb

bzw.

http://www.domain.de/seiten/infos/details.php?foo=blah&bar=blubb?cmtx_page=2&foo=blah&bar=blubb#cmtx_comments

Wobei er die Variablen dann doppelt dran hängt :/

Ich darf nicht beides nehmen sondern nur QSA:

RewriteRule ^(.*)/(.*)/site$ /seiten/infos/details.php?foo=$1&bar=$2 [QSA]

Klasse und ein dickes dickes Danke für den Denkanstoß :T
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #11
Nächstes Problem :coffee:

Klappt jetzt ja alles super - fast. Ich hab ja verschiedene Sprachen. Die werden am Ende der URL bestimmt. Diese sieht dann z.B. so aus:



Nun soll bei einem Kommentar unter das "en" entfernt werden da bei jedem Kommentar, egal von welcher Sprache aus, die selbe URL in die Datenbank geschrieben werden soll. Nun habe ich zum Testen mal folgendes probiert:

[src=php]$search = array('/en', '/pl', '/nl', '/dk', '/cz', '/es', '/fr', '/it');
$replace = array('/', '/', '/', '/', '/', '/', '/', '/');
$cmtx_url = str_replace($search, $replace, $cmtx_url);
echo $cmtx_url;[/src]

Wenn ich nun die $cmtx_url per echo ausgebe ändert sich nichts an der URL. Weshalb kann ich $cmtx_url hier nicht überschreiben? Jemand eine Idee?

Gruß godlike

PS: Ja ich weiß das dies keine praktikable Vorgehensweise ist. Sollte nur zum Test sein ob sich die Variable ändert ;)

Update:

Ok, nutze ich strg_replace nach dem include von der commentics.php klappt es. Eigentlich auch logisch. Fragt sich also nur wo ich in dem blöden Script das genau ausführen muss :dozey:
 
Zuletzt bearbeitet:
Kanns hier gerade nicht testen, würde das aber grundsätzlich so lösen:

[src=php]$cmtx_url = substr($cmtx_url, 0, strrpos($cmtx_url, '/'))[/src]

J.
 
  • Thread Starter Thread Starter
  • #13
Wie gesagt, das "wie" stand noch gar nicht fest, war ja nur zum testen. Ich verstehe nicht wie man diese $cmtx_url neu belegen kann. Laut sollte das doch gehen. Ok, wohl dann nicht über die $cmtx_url sondern über $cmtx_parameters. Allerdings habe ich keine Ahnung wie ich da auf meine angehängten Sprach-Identifier zugreifen könnte.

Im Nachhinein war der Versuch die Variable zu überschreiben auch selten blöde von mir :D ISt ja klar das die irgendwo im Script neu gesetzt wird :m Sonst fällt mir dazu aber nichts ein. Zur Not direkt beim INSERT ändern. Wollte ungern so massiv im Script pfuschen.
 
Axxo, nu versteh ich... glaub ich jedenfalls :)

Das Symptom war ja, dass trotz selektierter Page 2 der Inhalt der ersten Page angezeigt wird, richtig?

In der Doku steht, dass alle Querystring-Parameter, die nicht in $cmtx_parameters stehen, automatisch vom Script entfernt bzw. nicht durchgeschleift werden.

Also sollte rein theoretisch
[src=php]$cmtx_parameters = 'foo,bar';[/src]

dieses Symptom beheben. Wobei ich Deine Variablen-Platzhalter ^^ einfach mal übernommen habe, die müssen dann noch entsprechend angepasst werden.

J.
 
  • Thread Starter Thread Starter
  • #15
Ja, das hast du korrekt gesehen. Seltsam ist nur, wenn ich mit $cmtx_parameters = 'en' z.B. das /en von der url weg haue, zeigt er mir das komplette Kommentar-Scrip nicht mehr an. Der Platz ist einfach leer. Keine Meldung, nix :unknown: Somit kann ich nicht mal prüfen was jetzt genau mit der url passiert ist.
 
Du hattest bisher imho nicht den Parameter für die Sprachversion genannt, pack den doch einfach mit in $cmtx_parameters mit rein...
 
  • Thread Starter Thread Starter
  • #17
Habe ich ja probiert ;) Also so z.B.:

$cmtx_parameters = 'en, cz, dk, fr, it';

rufe ich dann z.B. auf kommt anstelle der Kommentarfunktion einfach gar nichts. Nicht mal per error_reporting(E_ALL) :confused:

hier mal der ganze code:

[src=php] $cmtx_parameters = 'en,cz,dk,fr,it'; // die Sprachparameter
$cmtx_identifier = $zeile['id']; // eindeutige ID aus der Datenbank
$cmtx_reference = $zeile['name']; // Name der Seite
$cmtx_path = $_SERVER['DOCUMENT_ROOT'].'sites/comments/';
require $cmtx_path.'includes/commentics.php';[/src]
 
Das sind doch nur die möglichen Werte des QS-Parameters (dessen Namen ich nicht kenne^^).
Du brauchst den Parameter selber...

Du hast doch in der pre-rewritten URL irgendwas wie hxxp://www.domain.de/seiten/infos/details.php?foo=blah&bar=blubb&lang=de&cmtx_page=2#cmtx_comments

Oder andernfalls - wie hast Du die Sprachselektion denn umgesetzt?
 
  • Thread Starter Thread Starter
  • #19
Nein, leider wird die Sprache noch über eine andere PHP-Seite bestimmt da, zusätzlich zum Inhalt, auf ein komplett anderes Layout zugegriffen wird. Sprich so:

RewriteRule ^(.*)/(.*)/en$ /seite_en.php?foo=$1&bar=$2 [QSA,L]
RewriteRule ^(.*)/(.*)/$ /seite.php?foo=$1&bar=$2 [QSA,L]

aus

RewriteRule ^(.*)/(.*)/en$ /seite_en.php?foo=$1&bar=$2 [QSA,L]
wird


und aus

RewriteRule ^(.*)/(.*)/$ /seite.php?foo=$1&bar=$2 [QSA,L]

wird

Referenziert wird das ganze über die ID. Sprich und greifen beide z.B. auf die ID 12345 zu. Diese bestimmt auch welche Kommentare wo auftauchen. Es geht mir nun eigentlich nur darum das, egal ob jemand von oder oder eben jeweils der Selbe, nennen wir ihn "Hauptlink" per Mail verschickt und auch so in meine Datenbank eingetragen wird. Ich habe es so verstanden das dieser Link, unabhängig über die ID, welche zuständig ist wo welcher Kommentar auftaucht, per $cmtx_url definiert wird. Für was anderes ist der ja eigentlich gar nicht nutze. Ok, außer andere Nutzer nehmen $cmtx_url als Identifier (was imho Blödsinn wäre da sich eine URL auch ändern kann, die ID nicht).

Hoffe ich konnte es einigermaßen verständlich erklären ;)

Update:

So, hab die Stelle gefunden. Ist in der pages.php folgende Funktion:

[src=php]function cmtx_create_page() { //create page

global $cmtx_identifier, $cmtx_reference, $cmtx_url, $cmtx_mysql_table_prefix, $cmtx_page_id; //globalise variables

//sanitize data
$cmtx_identifier = cmtx_sanitize($cmtx_identifier, true, true);
$cmtx_reference = cmtx_sanitize($cmtx_reference, true, true);
$cmtx_url = cmtx_sanitize($cmtx_url, true, true);

cmtx_db_query("INSERT INTO `" . $cmtx_mysql_table_prefix . "pages` (`identifier`, `reference`, `url`, `is_form_enabled`, `dated`) VALUES ('$cmtx_identifier', '$cmtx_reference', '$cmtx_url', 1, NOW())");

$cmtx_page_id = cmtx_db_insert_id();

}[/src]

Jetzt kann ich abfragen ob eine Sprache gewählt wurde die ungleich 'de' ist und den Link abschneiden.

[src=php]if ($lang != 'de') {
$cmtx_url = 'Test';
}[/src]
Irgendwie noch unsauber aber was anderes fällt mir auch nicht ein :/
 
Zuletzt bearbeitet:
Zurück
Oben