Mal 'ne Frage (update2)

Dienstag, 10.10.2017, 13:00 > da]v[ax

Sind hier PHP/MySQL-Experten anwesend?

Das WordPress-Plugin Subscribe to Comments Reloaded (auch auf GitHub) hat offenbar einen Bug in der Datenbankabfrage und zeigt im Adminbereich das "letzte" Abo mehrere 1000 Mal an.

Update: längliche Untersuchungen haben mir jetzt gezeigt, dass das Plugin offenbar an einem Tag durchgedreht ist und 1.4 Mio Einträge innerhalb weniger Minuten erzeugt hat. Ich kümmere mich am Wochenende darum. Mein Dank geht an kalo und woogie morgi, die mich in die richtige Richtung gestupst haben.

Sieht dann so aus:

obwohl in Wirklichkeit nur eine Handvoll Einträge in der Tabelle ist:

Hat jemand von euch vielleicht Lust, sich mal den Code anzugucken um mir zu sagen, wo der Bug steckt? Ich vermute ja, dass $subscriptions falsch initialisiert wird, aber ich kann das in dem Chaos nicht finden. Es dauert auch ewig, bis diese Seite überhaupt angezeigt wird.

Update: Inzwischen weiß ich, dass $subscriptions in wp_subscribe_reloaded.php erzeugt wird und zwar über diese Query, die ich geistig nicht auseinanderklamüsert bekomme:

return $wpdb->get_results(
$wpdb->prepare(
"
SELECT pm.meta_id, REPLACE(pm.meta_key, '_stcr@_', '') AS email, pm.post_id, SUBSTRING(pm.meta_value, 1, 19) AS dt, SUBSTRING(pm.meta_value, 21) AS status, srs.subscriber_unique_id AS email_key
FROM $wpdb->postmeta pm
INNER JOIN {$wpdb->prefix}subscribe_reloaded_subscribers srs ON ( REPLACE(pm.meta_key, '_stcr@_', '') = srs.subscriber_email )
WHERE pm.meta_key LIKE %s
AND pm.meta_value LIKE '%%R'
AND pm.post_id = %d", $parent_comment_author_email, $comment_post_id
), OBJECT
);
} else {
$where_clause = '';
foreach ( $search_fields as $a_idx => $a_field ) {
$where_clause .= ' AND';
$offset_status = ( $a_field == 'status' && $search_values[$a_idx] == 'C' ) ? 22 : 21;
switch ( $a_field ) {
case 'status':
$where_clause .= " SUBSTRING(meta_value, $offset_status)";
break;
case 'post_id':
$where_clause .= ' post_id';
break;
default:
$where_clause .= ' SUBSTRING(meta_key, 8)';
}
switch ( $operators[$a_idx] ) {
case 'equals':
$where_clause .= " = %s";
$where_values[] = $search_values[$a_idx];
break;
case 'does not contain':
$where_clause .= " NOT LIKE %s";
$where_values[] = "%{$search_values[$a_idx]}%";
break;
case 'starts with':
$where_clause .= " LIKE %s";
$where_values[] = "{$search_values[$a_idx]}%";
break;
case 'ends with':
$where_clause .= " LIKE %s";
$where_values[] = "%{$search_values[$a_idx]}";
break;
default: // contains
$where_clause .= " LIKE %s";
$where_values[] = "%{$search_values[$a_idx]}%";
}
}
switch ( $_order_by ) {
case 'status':
$order_by = "status";
break;
case 'email':
$order_by = 'meta_key';
break;
case 'dt':
$order_by = 'dt';
break;
default:
$order_by = 'post_id';
}
$order = ( $_order != 'ASC' && $_order != 'DESC' ) ? 'DESC' : $_order;

// This is the 'official' way to have an offset without a limit
$row_count = ( $_limit_results <= 0 ) ? '18446744073709551610' : $_limit_results; return $wpdb->get_results(
$wpdb->prepare(
"
SELECT meta_id, REPLACE(meta_key, '_stcr@_', '') AS email, post_id, SUBSTRING(meta_value, 1, 19) AS dt, SUBSTRING(meta_value, 21) AS status, srs.subscriber_unique_id AS email_key
FROM $wpdb->postmeta
INNER JOIN {$wpdb->prefix}subscribe_reloaded_subscribers srs ON ( REPLACE(meta_key, '_stcr@_', '') = srs.subscriber_email )
WHERE meta_key LIKE '\_stcr@\_%%' $where_clause
ORDER BY $order_by $order
LIMIT $_offset,$row_count", $where_values
), OBJECT
);
}
}
// end get_subscriptions

Habt ihr eine Idee?

Update 2: aaalso. Wo soll ich anfangen? In der Tabelle wp_postmeta gab es 1,5 Millionen Zeilen mit einem META_KEY LIKE %_stcr@_%. Das ist natürlich Bullshit. Zusammen mit dem besten Admin der Welt habe ich letztes Wochenende nun diese sämtlichen Einträge gekillt. Es scheint noch alles zu funktionieren. Woher diese Zeilen kamen? Keine Ahnung. Jetzt sind sie auf jeden Fall weg...