WordPressのタイムスタンプによるバグっぽいのを修正してみた
- 2007年10月02日
- category:CMS
- Comment(0)
- Trackback(0)
現在MovableTypeからWordPressに移転計画を実施中なのですが、その途中にWordPressのバグっぽい動作を発見しました。
バグの概要
バージョン:WordPress ME 2.2.3
簡単に説明すると、パーマリンクのURLをタイムスタンプで表示するようにしていて、投稿した時間の「時間」、「分」、「秒」のどれかが00だった場合、その記事のパーマリンクのページのコメントや次(前)のエントリーなどが表示されなくなる(日別アーカイブと同じ動作になる)というものです。
調べてみたらまったく同じ状況の人がちらほらといるようでした。
普通ならこんな面倒なことは見て見ぬふりをしておとなしくパーマリンクを別の表記に変更するのですが、以前のMovableType時代からの記事と整合性を取るにはタイムスタンプを使わないといけないという状況です。メンドクセー。。。
とりあえず「時間」と「分」は管理ページから変更できるからまだいいんですが、「秒」は変更できないのでデータベースのデータを編集しないといけなくなります。投稿するたびに60分の1の確率にびびりながら投稿したくありません。なんとか修正できないものかとソースと格闘すること約2時間。とりあえず修正できました。
バグの原因
パーマリンクにタイムスタンプを使用した場合、そのURLがパーマリンクかどうか判断しているコードの一部が「/wp-includes/query.php」の下記部分のようです。
419 $qv['p'] = (int) $qv['p'];
420 $qv['page_id'] = (int) $qv['page_id'];
421 $qv['year'] = (int) $qv['year'];
422 $qv['monthnum'] = (int) $qv['monthnum'];
423 $qv['day'] = (int) $qv['day'];
424 $qv['w'] = (int) $qv['w'];
425 $qv['m'] = (int) $qv['m'];
426 if ( '' != $qv[’hour’] ) $qv[’hour’] = (int) $qv[’hour’];
427 if ( ” != $qv[’minute’] ) $qv[’minute’] = (int) $qv[’minute’];
428 if ( ” != $qv[’second’] ) $qv[’second’] = (int) $qv[’second’];
429
430 // Compat. Map subpost to attachment.
431 if ( ” != $qv[’subpost’] )
432 $qv[’attachment’] = $qv[’subpost’];
433 if ( ” != $qv[’subpost_id’] )
434 $qv[’attachment_id’] = $qv[’subpost_id’];
435
436 $qv[’attachment_id’] = (int) $qv[’attachment_id’];
437
438 if ( (” != $qv[’attachment’]) || !empty($qv[’attachment_id’]) ) {
439 $this->is_single = true;
440 $this->is_attachment = true;
441 } elseif ( ” != $qv[’name’] ) {
442 $this->is_single = true;
443 } elseif ( $qv[’p'] ) {
444 $this->is_single = true;
445 } elseif ( (” != $qv[’hour’]) && (” != $qv[’minute’]) &&(” != $qv[’second’]) && (” != $qv[’year’]) && (” != $qv[’monthnum’]) && (” != $qv[’day’]) ) {
446 // If year, month, day, hour, minute, and second are set, a single
447 // post is being queried.
448 $this->is_single = true;
449 } elseif ( ” != $qv[’static’] || ” != $qv[’pagename’] || !empty($qv[’page_id’]) ) {
450 $this->is_page = true;
451 $this->is_single = false;
452 } elseif ( !empty($qv[’s’]) ) {
453 $this->is_search = true;
454 } else {
重要なのは赤い部分。$qv[’hour’]等は、空のときは空文字、0のときは0が入っているようです。比較演算子が「!=」となっているので、変数が空の場合も0の場合も偽となってしまいます。ここは空文字の場合は偽、0の場合と真という振る舞いになるべきだと思われるので演算子は「!==」にしないといけないはずです。
バグの修正
そういうわけで修正。
419 $qv['p'] = (int) $qv['p'];
420 $qv['page_id'] = (int) $qv['page_id'];
421 $qv['year'] = (int) $qv['year'];
422 $qv['monthnum'] = (int) $qv['monthnum'];
423 $qv['day'] = (int) $qv['day'];
424 $qv['w'] = (int) $qv['w'];
425 $qv['m'] = (int) $qv['m'];
426 if ( '' !== $qv[’hour’] ) $qv[’hour’] = (int) $qv[’hour’];
427 if ( ” !== $qv[’minute’] ) $qv[’minute’] = (int) $qv[’minute’];
428 if ( ” !== $qv[’second’] ) $qv[’second’] = (int) $qv[’second’];
429
430 // Compat. Map subpost to attachment.
431 if ( ” != $qv[’subpost’] )
432 $qv[’attachment’] = $qv[’subpost’];
433 if ( ” != $qv[’subpost_id’] )
434 $qv[’attachment_id’] = $qv[’subpost_id’];
435
436 $qv[’attachment_id’] = (int) $qv[’attachment_id’];
437
438 if ( (” != $qv[’attachment’]) || !empty($qv[’attachment_id’]) ) {
439 $this->is_single = true;
440 $this->is_attachment = true;
441 } elseif ( ” != $qv[’name’] ) {
442 $this->is_single = true;
443 } elseif ( $qv[’p'] ) {
444 $this->is_single = true;
445 } elseif ( (” !== $qv[’hour’]) && (” !== $qv[’minute’]) &&(” !== $qv[’second’]) && (” != $qv[’year’]) && (” != $qv[’monthnum’]) && (” != $qv[’day’]) ) {
446 // If year, month, day, hour, minute, and second are set, a single
447 // post is being queried.
448 $this->is_single = true;
449 } elseif ( ” != $qv[’static’] || ” != $qv[’pagename’] || !empty($qv[’page_id’]) ) {
450 $this->is_page = true;
451 $this->is_single = false;
452 } elseif ( !empty($qv[’s’]) ) {
453 $this->is_search = true;
454 } else {
これでちゃんと動作するようなりました。ただしコアなファイルの修正になるので、別のところで不具合がでるかもしれません(今のところ問題ないみたいですが)。もしこの記事をみて修正される方は完全に自己責任で行ってください。当サイトでは一切の責任を負いません。
とりあえず次のバージョンでは修正されてることを期待しましょ。
- Prev Entry
- WordPressで改行を変換しないようにするプラグイン
- Next Entry
- FireWorksCS3に組み込まれているフォームボタンを使う方法
