昨日、recently_commented_onが正常に作動しない(各エントリーの最新のコメントではなく、最初についたコメントの時刻順にソートされてしまう)ことについてエントリーを書いた(「アップグレードしたのはよいが・・・」)。具体的にどのようになるかというと
3.2-ja-2をそのまま適用![]() | ContextHandlers.pmを書き換え![]() |
ちょっと見づらいかもしれないけど、「「良い一週間」でありますように☆」と「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でどのように稼働するのかは未確認。
あとはどなたか詳しい人が解決してくれることを待ちましょう!(笑)


条件式が上下で違うのが激しく違和感。
前半はこー(※末尾添付)しないと後半の比較式と揃わないのでは。
というのも、降順でソートされるべきところが昇順(ちゅーか既定の順)になってるから
期待する順序で表示がされてないのではないかと思っております。
{ ‘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;
}
—-
でもこれじゃ動作変わりそうには見えませんよね…
MT::ConfigMgr->instance()->ObjectDriver
の返す値が激しく気になるお年頃。
ああ!なんか分かってきたような希ガス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
の返す値がハゲしく気になる秋の夜更け。
あ、いや、なんか思ったようにならんなあ・・・(滝汗
もーちょい前をまじめに読んでみたんですが、
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の値が気になる週末。
postgresを使っていないのに、モジュールがないと言われているのが気になります。
mt.cfgをもう一度確認してみてはいかがでしょう。
ObjectDriver DBI::SQLite
となっていますか?
あとは、このバージョンのバグでこの辺の設定を正しく読めていないのかも。
ObjectDriver.pm(このバージョンにこのモジュールがあるかは分かっていない)とか
と、MTを見たことも触ったことも無い、適当にぐぐっただけの俺が無責任に書いてみる
>postgresを使っていないのに、モジュールがないと言われている
いや、この場合は単なるチェックプログラムなので、
MySQL、Postgre、SQLiteについてそれぞれ調べて、
これはインストールされてます、これはされてません
っていう状況を表示するだけなのです。
特段のエラーメッセージというわけではありまっしぇん。
なんか頭痛くなってきたからもうやめたい>この話題(苦笑
TBありがとうございます。
何が原因なのか・・・コメント欄は文系人間の私にはさっぱり分からない世界です(笑)。
私は、日和って、コメント一覧をrecently_commented_onを使わない形で書き直して対応してしまいました・・・
>文系人間の私にはさっぱり分からない世界
私も、あんまり分かってなかったりします(爆笑)
でも、プログラムってよく見ると、けっこう文学的なんですよ。
もし何々ならこれこれしなさい if(何々){これこれ;}
それ以外の時はあれしなさい else{あれ;}
なんていうふうに文脈がつながっているので、
そのへんを読み解く楽しさみたいなのはありますね。
聞きかじり(しかもうろ覚え)ですが、
「プログラムを作るには数学的能力よりも語学的能力が重要」
と聞いたか言われたかしたことがあります。
思ったとおりではなく言ったとおりに動くのがプログラムなので
「如何に意思を間違いなく伝えるか」なんですよね。
…(大いに反省中、というかもうプログラマはやめてるもんね、私)
>postgresを使っていないのに、モジュールがないと言われている
ってのは、mt-check.cgi実行時にエラーになるってところについて言いました。
今回問題となっている箇所も、mt-check.cgiも
MT::ConfigMgr->instance()->ObjectDriver
を呼んでいるのかな。。。という推測でした。
もう終わっている話題に書いてすいません。
おかしい・・・