Kramer 與 get-recent-comments 的問題
我的 Recent Backlinks 自從升級到 wordpress 2.3 之後,就一直有問題,會多顯示出 kramer_pre%--> 的字樣。用這個奇怪的字樣去找,發現是 Kramer 這個 plug-in 的問題。當初會裝主要是因為 trackback 壞掉了,所以乾脆裝了 Kramer,會直接到網上找 back links,找到後代替 trackback auto-discovery 機制,插入資料到 wp_comments 表格。既然 Kramer 壞掉了,只好先拔掉再說。
沒想到拔掉 Kramer 之後,問題依舊,即使關掉 get-recent-comments 的 cache 也一樣。於是就直接進 database 裡找,發現不曉得為甚麼,Kramer 把製造出來的 wp_comments.comment_content 內容,前後加上了 <!--%kramer-pre%--> 與 <!--%kramer_post%-->。所以,只好辛苦地,寫個 script 修正 database:
#!/usr/bin/perl -w
use strict;
use utf8;
use File::Basename;
use Getopt::Long;
use DBI;
my ($__exe_name__) = (basename($0));
my ($__revision__) = ('$Rev: 26 $' =~ m/(\d+)/o);
my ($__rev_date__) = ('$Date: 2007-11-02 15:41:31 +0800 (五, 02 11 2007) $' =~ m/(\d{4}-\d{2}-\d{2})/o);
sub usage
{
print STDERR <<"EOF";
Usage: $__exe_name__ [ <option> ... ] <db-name>
Query wordpress database <db-name> and fix bad wp_comments.comment_content
generated by Kramer plug-in.
Options:
--help Show this help messages.
-h,--hostname <db-host> Connect to database hosted at <db-host>.
-u,--username <db-user> Use username <db-user> to log into database.
-p,--password <db-pass> Use password <db-pass> to log into database.
-v,--verbose Show verbose messages.
Revision: r$__revision__ ($__rev_date__)
EOF
exit;
}
sub msg_exit
{
my $ex = ((scalar(@_) > 0) ? shift @_ : 0);
foreach my $m (@_) {
print STDERR "ERROR: $m\n";
}
print STDERR <<"EOF";
Usage: $__exe_name__ [ <option> ... ] <db-name>
Type '$__exe_name__ --help' for usage.
EOF
exit($ex);
}
my $opt_verbose = 0;
my %db_options;
if (!GetOptions('help' => sub { usage; },
'h|hostname=s' => sub { $db_options{'DB_HOST'} = $_[1]; },
'u|username=s' => sub { $db_options{'DB_USER'} = $_[1]; },
'p|password=s' => sub { $db_options{'DB_PASS'} = $_[1]; },
'v|verbose' => \$opt_verbose)) {
msg_exit(0);
}
$db_options{'DB_NAME'} = shift @ARGV or msg_exit(1, 'Missing <db-name>.');
my $dbh = DBI->connect(
sprintf('DBI:mysql:database=%s;host=%s',
$db_options{'DB_NAME'},
$db_options{'DB_HOST'}),
$db_options{'DB_USER'},
$db_options{'DB_PASS'}
);
my @update_statements;
my $sth = $dbh->prepare(<<SQL
SELECT *
FROM wp_comments
WHERE comment_type ="pingback" AND
comment_content LIKE "<!--%"
SQL
);
$sth->execute();
while (my $row = $sth->fetchrow_hashref()) {
my @sqlpart_setval;
my @sqlpart_where;
foreach my $f (keys %$row) {
my $v = $row->{$f};
if ($f eq 'comment_content') {
# push(@sqlpart_setval, sprintf('-- WAS: "%s"', $v));
$v =~ s/^<!--%kramer-pre%-->//o;
$v =~ s/<!--%kramer-post%-->$//o;
push(@sqlpart_setval, sprintf('%s = %s', $f, $dbh->quote($v)));
}
else {
push(@sqlpart_where, sprintf('%s = %s', $f, $dbh->quote($v)));
}
}
push(@update_statements, sprintf(
"UPDATE\n\t%s\nSET\n\t%s\nWHERE\n\t%s;",
$arg_tab_name,
join(",\n\t", @sqlpart_setval),
join(" AND\n\t", @sqlpart_where)
));
}
$sth->finish();
foreach my $sql (@update_statements) {
print "-- --------------------------------------------- --\n$sql\n\n";
}
$dbh->disconnect();
利用這個 script,可以 dump 出一個 SQL 檔,備份好 wordpress 之後,把這個 SQL 檔餵進資料庫即修正完畢。
清掉 get-recent-comments 的 cache 之後,奇怪的字樣雖然不見了,不過正常該有的內容,卻又被截掉了最前面 5 個字元。繼續用 comment_excerpt 當關鍵字翻 get-recent-comments.php,發現了和 5 相關的下面這段程式:
if ($comment->comment_type == 'pingback')
{
$comment_type = "Pingback";
list($comment_author,$trackback_title) = kjgrc_parse_pingback($comment->comment_author);
if(strpos($comment_excerpt,'[...]') == 0)
$comment_excerpt = trim(substr($comment_excerpt,5));
if(strpos($comment_excerpt,'[...]') == strlen($comment_excerpt)-5)
$comment_excerpt = trim(substr($comment_excerpt,0,strlen($comment_excerpt)-5));
}
意思是說,如果 $comment_excerpt 最前面的 [...] 與最後面的 [...] 移掉。看到 strpos() 我就感到不對,查了一下文件,strpos() 若找不到就會回傳 FALSE,而 FALSE == 0 會得到真值,於是$comment_excerpt 前面的 5 個字元就被砍掉了。解法很簡單,把 == 改成 === 就可以了,如下:
--- get-recent-comments.php.ori 2007-11-02 17:31:56.000000000 +0800
+++ get-recent-comments.php 2007-11-02 17:32:13.000000000 +0800
@@ -1248,7 +1248,7 @@
$comment_type = "Pingback";
list($comment_author,$trackback_title) = kjgrc_parse_pingback($comment->comment_author);
- if(strpos($comment_excerpt,'[...]') == 0)
+ if(strpos($comment_excerpt,'[...]') === 0)
$comment_excerpt = trim(substr($comment_excerpt,5));
if(strpos($comment_excerpt,'[...]') == strlen($comment_excerpt)-5)
$comment_excerpt = trim(substr($comment_excerpt,0,strlen($comment_excerpt)-5));
至此,問題全部解決,同時回應給 get-recent-comments team。不過,又回想了一下,共 5 個字元被砍掉,那一開始的那個奇怪的 kramer-pre%--> 字樣,不就是 Kramer 塞進來的 <!--%kramer-pre%--> 扣掉前面 5 個字元嗎?
繞了一圈才發現,原來問題的癥結在於 get-recent-comments,而不是 Kramer,我錯怪它了。不過我還沒決定是否要把 Kramer 裝回去就是了。
Post a Comment