recently_commented_onの挙動不審について

昨日、recently_commented_onが正常に作動しない(各エントリーの最新のコメントではなく、最初についたコメントの時刻順にソートされてしまう)ことについてエントリーを書いた(「アップグレードしたのはよいが・・・」)。具体的にどのようになるかというと

3.2-ja-2をそのまま適用
recently_commented_on_1.jpg
 ContextHandlers.pmを書き換え
recently_commented_on_2.jpg

ちょっと見づらいかもしれないけど、「「良い一週間」でありますように☆」と「Upgrade!」が逆に表示されているのが分かると思う。
この件について、同じような症状が現れたという47thさんからさっそくコメントをいただいた。ということは・・・この問題は私に固有の問題ではなくて、もしかしてLolipop+SQLiteの場合に現れる症状なのかな?
なにぶんまだ情報が少ないので、可能性の一つとして、ということだけど。
ちなみに私もLolipopのレンタルサーバーを使ってるわけだけど、mt-check.cgiを実行すると

サーバーに、「DBD::Pg」がインストールされていない、古いバージョンがインストールされている、もしくは「DBD::Pg」に必要なモジュールがインストールされていません 「DBI」と「DBD::Pg」は、PostgreSQLを使ってデータを管理するために必要です。「DBD::Pg」をインストールする場合は、インストール手順を参照してください。

と表示される。PostgreSQLは使わないので、私の場合は関係ないはず、と思ってスルーしてるけど、なにかこのへんも関係あるのでしょうか・・・???


念のため、各バージョンでの関係箇所を抜き書きしておく。
Movable Type 3.171 (/lib/MT/Template/Context.pm)

} elsif (my $n = $args->{recently_commented_on}) {
$args{‘join’} = [ ‘MT::Comment’, ‘entry_id’,
{ blog_id => $blog_id, visible => 1 },
{ ‘sort’ => ‘created_on’,
direction => ‘descend’,
unique => 1,
limit => $n } ];
$no_resort = 1;
}
@entries = MT::Entry->load(\%terms, \%args);

Movable Type 3.2 ja (/lib/MT/Template/ContextHandlers.pm)

@entries = MT::Entry->load(\%terms, \%args);
if ($args->{recently_commented_on}) {
my @e = sort {$b->comment_latest->created_on <=> $a->comment_latest->created_on}
grep {$_->comment_latest} @entries;
@entries = splice(@e, 0, $args->{recently_commented_on});
$no_resort = 1;
}

Movable Type 3.2 ja 2 (/lib/MT/Template/ContextHandlers.pm)

} elsif (my $n = $args->{recently_commented_on}) {
if (MT::ConfigMgr->instance()->ObjectDriver !~ /postgres/) {
require MT::Comment;
$args{‘join’} = [ ‘MT::Comment’, ‘entry_id’,
{ blog_id => $blog_id, visible => 1 },
{ ‘sort’ => ‘created_on’,
direction => ‘descend’,
unique => 1,
limit => $n } ];
$no_resort = 1;
} else {
$args{‘join’} = [ ‘MT::Comment’, ‘entry_id’,
{ blog_id => $blog_id, visible => 1 },
{ unique => 1 }];
}
}
@entries = MT::Entry->load(\%terms, \%args);
if ($args->{recently_commented_on}
&& MT::ConfigMgr->instance()->ObjectDriver =~ /postgres/) {
my @e = sort {$b->comment_latest->created_on <=> $a->comment_latest->created_on}
@entries;
@entries = splice(@e, 0, $args->{recently_commented_on});
$no_resort = 1;
}

私の場合、3.171から3.2-ja-2へとアップグレードしたので、3.2でどのように稼働するのかは未確認。
あとはどなたか詳しい人が解決してくれることを待ちましょう!(笑)

recently_commented_onの挙動不審について」への12件のフィードバック

  1. 条件式が上下で違うのが激しく違和感。
    前半はこー(※末尾添付)しないと後半の比較式と揃わないのでは。
    というのも、降順でソートされるべきところが昇順(ちゅーか既定の順)になってるから
    期待する順序で表示がされてないのではないかと思っております。
    { ‘sort’ => ‘created_on’,
    direction => ‘descend’,
    unique => 1,
    limit => $n }
    のあたりが全然適用されてないんじゃないか疑惑。
    でも自分で動かしてるわけではないので黙って(w おこうかな、と。
    —-
    } elsif (my $n = $args->{recently_commented_on}) {
    if (MT::ConfigMgr->instance()->ObjectDriver =~ /postgres/) {
    $args{‘join’} = [ ‘MT::Comment’, ‘entry_id’,
    { blog_id => $blog_id, visible => 1 },
    { unique => 1 }];
    } else {
    require MT::Comment;
    $args{‘join’} = [ ‘MT::Comment’, ‘entry_id’,
    { blog_id => $blog_id, visible => 1 },
    { ‘sort’ => ‘created_on’,
    direction => ‘descend’,
    unique => 1,
    limit => $n } ];
    $no_resort = 1;
    }
    }
    @entries = MT::Entry->load(\%terms, \%args);
    if ($args->{recently_commented_on}
    && MT::ConfigMgr->instance()->ObjectDriver =~ /postgres/) {
    my @e = sort {$b->comment_latest->created_on $a->comment_latest->created_on}
    @entries;
    @entries = splice(@e, 0, $args->{recently_commented_on});
    $no_resort = 1;
    }
    —-

  2. でもこれじゃ動作変わりそうには見えませんよね…
    MT::ConfigMgr->instance()->ObjectDriver
    の返す値が激しく気になるお年頃。

  3. ああ!なんか分かってきたような希ガスw
    これは全ての人に共通の現象ではなくて、LolipopのサーバーでSQLiteにしてる人に起きる現象のようなので、スクリプトの基本は間違ってないと思うのですよ。
    なはさんの言ってるdescendは、エントリーの並び順じゃなくて各エントリー内のコメントの並び順なので、たぶんノー問題。
    それよりも、その下の方に
    unless ($no_resort) {
    my $so = $args->{sort_order} || $ctx->stash(‘blog’)->sort_order_posts || ”;
    my $col = $args->{sort_by} || ‘created_on’;
    @entries = $so eq ‘ascend’ ?
    sort { $a->$col() cmp $b->$col() } @entries :
    sort { $b->$col() cmp $a->$col() } @entries;
    }
    っつーのがあるので、エントリーの並び順を決めてるのはこっちの方ですね、たぶん?
    $no_resortの値が1か0かによって挙動が変わるので、そのあたりを正しく取得できていないのが原因?
    なので私も、
    MT::ConfigMgr->instance()->ObjectDriver
    の返す値がハゲしく気になる秋の夜更け。

  4. あ、いや、なんか思ったようにならんなあ・・・(滝汗

  5. もーちょい前をまじめに読んでみたんですが、
    if (my $last = $args->{lastn}) {
    ※省略
    } elsif (my $days = $args->{days}) {
    ※省略
    } elsif (my $n = $args->{recently_commented_on}) {
    ※省略
    $no_resort = 1;
    } else {
    ※省略
    }
    }
    @entries = MT::Entry->load(\%terms, \%args);
    if ($args->{recently_commented_on}
    && MT::ConfigMgr->instance()->ObjectDriver =~ /postgres/) {
    ※省略
    $no_resort = 1;
    }
    かなり端折ってますが、
    ・最初のifもしくは次のelsifに引っかかる
    ・ObjectDriverがPostgreSQLではない
    場合ってのは$no_resort=0のままですよね。
    全部きっちり読んでませんがこのあたりってどうなんでしょう。
    やっぱりObjectDriverの値が気になる週末。

  6. postgresを使っていないのに、モジュールがないと言われているのが気になります。
    mt.cfgをもう一度確認してみてはいかがでしょう。
    ObjectDriver DBI::SQLite
    となっていますか?
    あとは、このバージョンのバグでこの辺の設定を正しく読めていないのかも。
    ObjectDriver.pm(このバージョンにこのモジュールがあるかは分かっていない)とか
    と、MTを見たことも触ったことも無い、適当にぐぐっただけの俺が無責任に書いてみる

  7. >postgresを使っていないのに、モジュールがないと言われている
    いや、この場合は単なるチェックプログラムなので、
    MySQL、Postgre、SQLiteについてそれぞれ調べて、
    これはインストールされてます、これはされてません
    っていう状況を表示するだけなのです。
    特段のエラーメッセージというわけではありまっしぇん。
    なんか頭痛くなってきたからもうやめたい>この話題(苦笑

  8. TBありがとうございます。
    何が原因なのか・・・コメント欄は文系人間の私にはさっぱり分からない世界です(笑)。
    私は、日和って、コメント一覧をrecently_commented_onを使わない形で書き直して対応してしまいました・・・

  9. >文系人間の私にはさっぱり分からない世界
    私も、あんまり分かってなかったりします(爆笑)
    でも、プログラムってよく見ると、けっこう文学的なんですよ。
    もし何々ならこれこれしなさい  if(何々){これこれ;}
    それ以外の時はあれしなさい   else{あれ;}
    なんていうふうに文脈がつながっているので、
    そのへんを読み解く楽しさみたいなのはありますね。

  10. 聞きかじり(しかもうろ覚え)ですが、
    「プログラムを作るには数学的能力よりも語学的能力が重要」
    と聞いたか言われたかしたことがあります。
    思ったとおりではなく言ったとおりに動くのがプログラムなので
    「如何に意思を間違いなく伝えるか」なんですよね。
    …(大いに反省中、というかもうプログラマはやめてるもんね、私)

  11. >postgresを使っていないのに、モジュールがないと言われている
    ってのは、mt-check.cgi実行時にエラーになるってところについて言いました。
    今回問題となっている箇所も、mt-check.cgiも
    MT::ConfigMgr->instance()->ObjectDriver
    を呼んでいるのかな。。。という推測でした。
    もう終わっている話題に書いてすいません。

コメントは停止中です。