Google Crisis Response(Google)
災害に関する情報源や、行方不明者情報の収集と検索を行う『パーソンファインダー』を初めとするツールの提供が行われています。

2008年11月29日 土曜日

WordPress 用プラグイン monthchunks のバグを修正

Filed under: WordPress,ハック,プラグイン
タグ:, , ,
時間:3時45分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

 このブログでは、月ごとアーカイブをコンパクトに表示してくれるプラグイン monthchunks を使用していますが、記事がないのに表示されている月があることが判明しました。

 問題の月は、2006年の9月。Google ウェブマスターツールのリンクエラー報告によると、76箇所で表示されているとのこと。さすがに数が多いので、本腰を入れて調べてみることにしました。久しぶりのプラグインハックです。

 何はともあれ、まずはプラグインのコードを読みます。使用しているバージョンは、最新の2.1。関数が1つ定義してあるだけでコメントを含めても154行と非常に短いので、初めてのハックにはお勧めかもしれません。

 大まかな流れは、SQL 文を生成して実行するだけ。オプションによって多少分岐がありますが、上から追いかけていけば大したことはありません。101行目からと114行目(110行目から始まる foreach の中)からの2箇所でデータベースにアクセスしています。1箇所目は記事のある年度の取得、2箇所目は各年度別に記事のある月の取得をしています。

  1. // get an array of the years in which there are posts
  2.     $wpdb->query("SELECT DATE_FORMAT(post_date, '%Y') as post_year
  3.                  FROM $wpdb->posts
  4.                  WHERE post_status = 'publish'
  5.                  GROUP BY post_year
  6.                  HAVING post_year <> '0000'
  7.                  ORDER BY post_year $year_order");
  8.     $years = $wpdb->get_col();
  1. // get an array of months for the current year without leading zero
  2.         // sort by month with leading zero
  3.         $months = $wpdb->get_results("SELECT DATE_FORMAT(post_date, '%c') as post_month,
  4.                                      $month_format AS display_month,
  5.                                      DATE_FORMAT(post_date, '%M') as post_month_name
  6.                                      FROM $wpdb->posts
  7.                                      WHERE DATE_FORMAT(post_date, '%Y') = $year
  8.                                      AND post_status = 'publish'
  9.                                      GROUP BY DATE_FORMAT(post_date, '%m')
  10.                                      ORDER BY post_date");

 今回問題になっているのは月の情報なので、2箇所目を詳しく見ていきます。PHP のコードと SQL が混在してわかりにくいので、最終的な SQL 文を記述してみます。オプションを特に指定しない場合は、次のようなものが出来上がります。(改行やインデントなどを加えてあります)

  1. SELECT
  2.     DATE_FORMAT(`post_date`, '%c') AS `post_month`,
  3.     DATE_FORMAT(`post_date`, '%c') AS `display_month`,
  4.     DATE_FORMAT(`post_date`, '%M') AS `post_month_name`
  5. FROM `wp_posts`
  6. WHERE
  7.     DATE_FORMAT(`post_date`, '%Y') = 2006
  8.     AND post_status = 'publish'
  9. GROUP BY DATE_FORMAT(`post_date`, '%m')
  10. ORDER BY `post_date`;

 実際にこの SQL 文を手がかりに検索してみると、記事ではなく固定ページが見つかりました。記事と固定ページを区別していないため、固定ページしかない月も表示してしまっていたのです。

 ここまでわかればあとは簡単。検索条件に記事であることを加えればいいのです。記事の場合は post_type というフィールドの値が post となるので(WordPress 2.1以降)、post_type = 'post' を加えます。変更後は次のようになります。私は120行目に加えました。

  1. // get an array of months for the current year without leading zero
  2.         // sort by month with leading zero
  3.         $months = $wpdb->get_results("SELECT DATE_FORMAT(post_date, '%c') as post_month,
  4.                                      $month_format AS display_month,
  5.                                      DATE_FORMAT(post_date, '%M') as post_month_name
  6.                                      FROM $wpdb->posts
  7.                                      WHERE DATE_FORMAT(post_date, '%Y') = $year
  8.                                      AND post_status = 'publish'
  9.                                      AND post_type = 'post'
  10.                                      GROUP BY DATE_FORMAT(post_date, '%m')
  11.                                      ORDER BY post_date");

 これにより、その年の公開されている記事という条件で絞り込むことができるようになりました。現在2006年の9月は表示されなくなっています。

2010年6月21日追記

prioさんからコメントをいただきましたので、年度の表示についても追記します。確認はしていませんので、参考程度にどうぞ。

100行目からの年度のコードを見ると、月の取得同様に固定ページも含むようになっています。SQLにしてみるとこんな感じ。

  1. SELECT
  2.     DATE_FORMAT(post_date, '%Y') as post_year
  3. FROM `wp_posts`
  4. WHERE
  5.     post_status = 'publish'
  6. GROUP BY post_year
  7. HAVING post_year <> '0000'
  8. ORDER BY post_year DESC

記事の投稿に限定する条件を加えると次のようになります。

  1. // get an array of the years in which there are posts
  2.     $wpdb->query("SELECT DATE_FORMAT(post_date, '%Y') as post_year
  3.                  FROM $wpdb->posts
  4.                  WHERE post_status = 'publish'
  5.                  AND post_type = 'post'
  6.                  GROUP BY post_year
  7.                  HAVING post_year <> '0000'
  8.                  ORDER BY post_year $year_order");
  9.     $years = $wpdb->get_col();

104行目が追加した行です。意味については、月の場合と同じです。

Comments (2)

2008年11月24日 月曜日

『キノの旅 -the Beautiful World- Ⅶ』

Filed under: 読書中
タグ:, ,
時間:13時31分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

12巻です。まだ4話までを読んだだけですが、なんとなく重い雰囲気を感じ取っています。

説話的な話が多いのはいつものことですが、オビの『ねえキノ、死なないでね。』という台詞が気になります。カラーイラストのキノも表情が硬い。プロローグも気になります。

Comments (0)

2008年11月15日 土曜日

アンケートを設置しました

Filed under: WordPress,プラグイン
時間:16時10分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

 WordPress のシェアを知りたかったので、アンケートを設置しました。右ペインのカレンダーの下にありますので、気が向いたらお願いします。

 アンケートは、Democracy AJAX Poll というプラグインを使用しています。Ajax を使用することで、ページのリロードなしで投票できます。導入方法などについては、ぼのさんによる記事が参考になると思います。

 なお、日本語リソースは配布していたサイトが閉鎖してしまったため導入していません。普通に日本語が使えましたので、とりあえずはこのままで行く予定です。

Comments (0)

2008年11月8日 土曜日

『魔法戦士リウイ ファーラムの剣 嵐の海の魔法戦士』

Filed under: 読書中
タグ:, ,
時間:15時32分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

 ファーラムの剣を探すシリーズの6巻。今度の舞台は海の民の王国バイカル。前回の舞台であるイーストエンドからはそんなに遠くないようです。

 なお、富士見ファンタジア文庫が20周年だそうで、カバーのデザインが新しくなっています。

Comments (0)

2008年11月3日 月曜日

『local modification time does not match remote』の対処方法

Filed under: FreeBSD
時間:12時01分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

 FreeBSD の Ports でインストールしたアプリケーションのアップデートをしようとしたときのトラブルのメモです。

 私は普段 portupgrade で管理していますが、Smarty だけ同じエラーでアップデートできないでいました。

 ファイルがダウンロードできないというメッセージもあったので、Ports ツリーの問題だと思って様子を見ていました。ところが、1ヶ月経っても2ヶ月経っても状況は変化しないまま。さすがに違うようだと思い、最後に表示される次のエラーメッセージを検索してみることに。

local modification time does not match remote

 いくつかのサイトを見てみると、ダウンロードに失敗したりしたときになる模様。先ほどのエラーメッセージは、ファイル名は同じなのに中身が違うということのようです。『ローカルファイルの更新時間がサーバーのファイルと一致しない』という意味だと思ってましたので、ちょっとわかりにくかったです。

 対応策は、次のサイトの記事が参考になりました。

 この記事によると、手動で /usr/ports/distfiles/vim にファイルをダウンロードすればできたとのこと。早速 smarty というディレクトリを同じように作って、Smarty の公式サイトからダウンロードに失敗しているファイルである Smarty-2.6.14-docs.tar.gz をダウンロード。再度 portupgrade をしてみましたが変化なし。

 もしやと思って /usr/ports/distfiles を見てみると、そこにはすでに Smarty のファイルがありました。Smarty の場合はディレクトリなしのようです。早速ファイルを削除してからダウンロードしたファイルを移動して再度トライ。

 今度はうまくできました。

 まとめると、次のような感じでしょうか。

  1. port の更新やインストールでメッセージ『local modification time does not match remote』が表示された。
  2. /usr/ports/distfiles 以下にある該当のファイルを削除。
  3. 1をもう1度行う。
Comments (0)

HTML convert time: 2.079 sec. Powered by

Images is enhanced with WordPress Lightbox JS by Zeo