25
Feb
07

Wordpress PostRatings Vandalismus beheben

WP-PostRatings ist ein nettes Wordpress Plugin, mit welchem die Blog Leser für jeden Artikel eine Bewertung abgeben können. So erfährt man als Blogger welche Artikel besser ankommen als andere. Natürlich muss man auch einmal mit einer schlechten Bewertung rechnen; was einem vielleicht nicht gerade freut aber doch eine wertvolle Rückmeldung ist. Etwas ganz anderes ist aber die systematische, schlechte Bewertung durch einen Leser quer durch den ganzen Blog. Das hat mit einer Kritik der Artikelqualität wenig zu tun sondern grenzt an virtuellen Vandalismus.

Das Plugin merkt sich zwar die Aktionen der Bewertungen in einer MySQL Tabelle, jedoch gibt es keine einfache Möglichkeit gewissen Bewertungen im Adminbereich wieder zu entfernen. Da hilft nur der direkte Eingriff in die darunterligende MySQL Datenbank.

Ich möchte in diesem Artikel aufzeigen, wie man IP basiert WP-PostRatings Bewertungen aus dem System entfernt. Dazu muss man auf dem Server in die MySQL Konsole gehen und die Wordpress Datenbank auswählen. Zur zusätzlichen Sicherheit starten wir auch gleich eine neue Transaktion:

mysql> USE wordpress;
mysql> START TRANSACTION;

Als nächstes schauen wir uns die PostRatings Log Tabelle an, welches auch im Wordpress Administrationsbereich zugänglich ist (dort werden ich normalerweise auch auf die gezielten schlechten Bewertungen aufmerksam und merke mit dann die IP):

mysql> DESC wp_ratings;
+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| rating_id        | int(11)      |      | PRI | NULL    | auto_increment |
| rating_postid    | int(11)      |      |     | 0       |                |
| rating_posttitle | text         |      |     |         |                |
| rating_rating    | int(2)       |      |     | 0       |                |
| rating_timestamp | varchar(15)  |      |     |         |                |
| rating_ip        | varchar(40)  |      |     |         |                |
| rating_host      | varchar(200) |      |     |         |                |
| rating_username  | varchar(50)  |      |     |         |                |
| rating_userid    | int(10)      |      |     | 0       |                |
+------------------+--------------+------+-----+---------+----------------+

Somit können wir mit einem einfachen SQL Befehlt die betroffenen Artikel ID’s und die abgegebene Bewertung für eine bestimmte IP abfragen:

mysql> SELECT rating_postid, rating_rating FROM wp_ratings WHERE rating_ip='83.76.155.53';
+---------------+---------------+
| rating_postid | rating_rating |
+---------------+---------------+
|             3 |             1 |
|            38 |             1 |
+---------------+---------------+

Wenn nötig kann man das Resultat ja auch noch anhand weiterer Kritierien wie z.B. den Zeitstempel eingrenzen. Die aktuellen Werte welche das Plugin bei jedem Artikel anzeigt sind sehr generisch in einer Wordpress eigenen Metadaten-Tabelle abgelegt:

mysql> desc wp_postmeta;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| meta_id    | bigint(20)   |      | PRI | NULL    | auto_increment |
| post_id    | bigint(20)   |      | MUL | 0       |                |
| meta_key   | varchar(255) | YES  | MUL | NULL    |                |
| meta_value | longtext     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

Das Plugin speichert die Werte als drei verschiedene Schlüssel/Wertepaare ratings_users, ratings_score und ratings_average. Der Schlüssel ratings_users steht für die Anzahl abgegebenen Bewertungen, ratings_score für die gesamte Anzahl der Punkte aller Bewertungen und ratings_average für den daraus resultierenden Durchschnitt. Man benötigt also einen self-join um alle diese Informationen in Bezug auf den Artikel auszugeben. Desshalb kann man aber auch keine veränderbare View erstellen sondern muss mit einer temporären Tabelle arbeiten:

mysql> CREATE TEMPORARY TABLE
  tmp_postratings
SELECT
  a.post_id AS post_id,
  a.meta_id as users_meta_id,
  a.meta_value AS users,
  b.meta_id as score_meta_id,
  b.meta_value AS score,
  c.meta_id as average_meta_id,
  c.meta_value AS average
FROM
  wp_postmeta a,
  wp_postmeta b,
  wp_postmeta c
 WHERE
  a.post_id=b.post_id AND
  a.post_id=c.post_id AND
  a.meta_key='ratings_users' AND
  b.meta_key='ratings_score' AND
  c.meta_key='ratings_average';

Diese Tabelle kann nun verwendet werden um all die benötigten Informationen anzuzeigen. Mich interessiert nun aber gerade die in diesem Beispiel geänderten Artikel mit der ID 3 und 38, welche wir ja vorher aus dem Log extrahiert haben:

mysql> SELECT * FROM tmp_postratings WHERE post_id IN (3,38);
+---------+---------------+-------+---------------+-------+-----------------+---------+
| post_id | users_meta_id | users | score_meta_id | score | average_meta_id | average |
+---------+---------------+-------+---------------+-------+-----------------+---------+
|      38 |           424 | 2     |           425 | 6     |             426 | 3       |
|       3 |           730 | 1     |           731 | 1     |             732 | 1       |
+---------+---------------+-------+---------------+-------+-----------------+---------+

Natürlich kann man jetzt in der Tabelle die Werte einzeln anpassen, aber eleganter geht es, wenn wir gleich pro IP die Werte aus dem Log holen:

mysql> UPDATE tmp_postratings a LEFT JOIN wp_ratings b ON a.post_id = b.rating_postid
SET a.users=a.users-1, a.score=a.score-b.rating_rating
WHERE b.rating_ip='83.76.155.53';

Natürlich überprüfen wir das Resultat gleich:

mysql> SELECT * FROM tmp_postratings WHERE post_id IN (3,38);
+---------+---------------+-------+---------------+-------+-----------------+---------+
| post_id | users_meta_id | users | score_meta_id | score | average_meta_id | average |
+---------+---------------+-------+---------------+-------+-----------------+---------+
|      38 |           424 | 1     |           425 | 5     |             426 | 3       |
|       3 |           730 | 0     |           731 | 0     |             732 | 1       |
+---------+---------------+-------+---------------+-------+-----------------+---------+

Die Anzahl der Benutzer und auch der Gesamtwert ist nun korrigiert, den Durchschnitt müssen wir aber neu berechnen:

mysql> UPDATE tmp_postratings SET average=ROUND(score/users);

Da aber eine Division durch 0 als Resultat NULL ergibt, müssen wir diese Fälle noch extra auf 0 zurücksetzten:

mysql> UPDATE tmp_postratings SET average=0 WHERE average IS NULL;

Eine nochmalige Kontrolle bestätigt uns nun, dass die Werte korrekt sind:

mysql> SELECT * FROM tmp_postratings WHERE post_id IN (3,38);
+---------+---------------+-------+---------------+-------+-----------------+---------+
| post_id | users_meta_id | users | score_meta_id | score | average_meta_id | average |
+---------+---------------+-------+---------------+-------+-----------------+---------+
|      38 |           424 | 1     |           425 | 5     |             426 | 5       |
|       3 |           730 | 0     |           731 | 0     |             732 | 0       |
+---------+---------------+-------+---------------+-------+-----------------+---------+

Die Daten sind also korrekt und können wieder zurück in Wordpress Tabelle geschrieben werden. Zuerst die Anzahl der Bewertungen:

mysql> UPDATE wp_postmeta a LEFT JOIN tmp_postratings b ON a.meta_id = b.users_meta_id
SET a.meta_value = b.users WHERE a.meta_key='ratings_users';

Dann die Bewertungspunkte:

mysql> UPDATE wp_postmeta a LEFT JOIN  tmp_postratings b ON a.meta_id = b.score_meta_id
SET a.meta_value = b.score WHERE a.meta_key='ratings_score';

Und schlussendlich noch den Durchschnitt:

mysql> UPDATE wp_postmeta a LEFT JOIN tmp_postratings b ON a.meta_id = b.average_meta_id
SET a.meta_value = b.average WHERE a.meta_key='ratings_average';

Um ganz sicher zu sein überprüfen wir das Ergebniss nochmals:

mysql> SELECT
  a.post_id AS id,
  a.meta_value AS users,
  b.meta_value AS score,
  c.meta_value AS average
FROM
  wp_postmeta a,
  wp_postmeta b,
  wp_postmeta c
 WHERE
  a.post_id=b.post_id AND
  a.post_id=c.post_id AND
  a.meta_key='ratings_users' AND
  b.meta_key='ratings_score' AND
  c.meta_key='ratings_average' AND
  a.post_id IN (3,38);

Ist alles wie gewünscht bestätigen wir die wir die Transaktion mit COMMIT; oder brechen die ganze Geschichte mit einem ROLLBACK; ab.

Tja lieber Vandale, deine Arbeit ist also mit ein paar wenigen SQL Queries wieder zunichte gemacht, und beim nächsten Mal brauche ich dank diesem Artikel sogar noch weniger Zeit als du ;-)




3 Kommentare zu “Wordpress PostRatings Vandalismus beheben”



  1. Gravatar-Bild 1 Marco 11. Apr 2007 um 20:45

    Hallo Michi
    Ich bin auf der Suche nach einer Möglichkeit, das wp-plugin “postratings” auf Deutsch zu ändern, auf diesen Beitrag gestossen. Er beweist mir, dass es wirklich möglich ist, die Sprachausgabe anzupassen. Offensichtlich sind hier aber Profis am Werk. Ist die Anpassung auch für einen Laien möglich? Oder kannst du mit (mit einigen Hinweisen oder gar Code-Schnipseln) helfen? Wäre mega cool.

  2. Gravatar-Bild 2 michi 13. Apr 2007 um 14:57

    Hoi Marco

    Also die Texte für das Plugin selber sind in der Datei wp-postratings.pot abgelegt und können kopiert und anschliessend mit einem Texteditor angepasst werden. Dies betrifft jedoch nur die Texte, welche das Plugin im Administrationsbereich zeigt. Die Texte welche der benutzer im Blog selber sieht, können direkt im Administrationsbereich unter Ratings > Ratings Options geändert werden.

  3. Gravatar-Bild 3 Marco 13. Apr 2007 um 16:47

    Ciao Michi
    Super! Das war ja extremn einfach und schon fast peinlich, dass ich’s nicht selber rausfand. Mein Lösungsansatz war total falsch. Herzlichen Dank für deine Hilfe.

Kommentare sind zur Zeit deaktiviert.

März 2010
M D M D F S S
« Jun    
1234567
891011121314
15161718192021
22232425262728
293031  

Werbung


Buttonitis