MagpieRSSのしつこいキャッシュに悩みました

概要

WordPress(現在バージョン3.2.1)には、RSSフィードをパースするための、MagpieRSSベースの機能がついてます。

include_once(ABSPATH . WPINC . ‘/rss.php’);
$rss = fetch_rss(‘$feedurl’);

これを利用して、WordPressで作成した別のサイトのRSSフィードを読み込んで、表示させる仕組みを作っています。
1回目の表示は簡単にできました。
2回目、本文の抜粋表示の長さと「続きを読む」の表示まわりを調整して再表示を試みましたが、さっきと全く変わりません。
ブラウザのキャッシュを消しても変わりません。

調査

出力側がおかしいのか、読み込んで表示させる方がおかしいのか・・・。

フィードはブラウザに表示させて、変更点が反映されているこをと確認したので、問題は読み込み側、どうやらキャッシュが怪しいというところまで分かりました。

その後ソースを追ったり、DBのキャッシュ(wp_optionテーブルにRSSとキャッシュの有効期限が格納されます)をチェックしたりして、定数に不適切な値をセットしたのが原因と分かりました。

まとめ

MagpieRSS(/p-includes/rss.php)のデフォルト設定では、「キャッシュを使用」、「有効期限はセットしてから3600秒」になっています。

define(‘MAGPIE_CACHE_ON’, 1);
define(‘MAGPIE_CACHE_AGE’, 3600);

この値は、呼び出し側で上書きできます。
キャッシュの有効期限がすぐくるように、

define('MAGPIE_CACHE_AGE', 0);

と書きました。表示内容に変化は起こりません。その後 MAGPIE_CACHE_AGE に別の値を入れても、何も変わりません。
理由は以下のコードにあります。

class RSSCache {
var $BASE_CACHE; // where the cache files are stored
var $MAX_AGE = 43200; // when are files stale, default twelve hours
var $ERROR = ”; // accumulate error messages
function RSSCache ($base=”, $age=”) {
$this->BASE_CACHE = WP_CONTENT_DIR . ‘/cache’;
if ( $base ) {
$this->BASE_CACHE = $base;
}
if ( $age ) {
$this->MAX_AGE = $age;
}
}

RSSCache のコンストラクタの引数$ageに MAGPIE_CACHE_AGE が渡されます。
$ageに0が渡されると$MAX_AGEはデフォルトの43200(12時間)になります。
一度12時間後にセットされてしまったので、その後キャッシュの有効期限をいくら小さい値に変えても影響しないわけです。

DBのキャッシュを消して、新たに作成したキャッシュの保存期限を念のため調べてみたら12時間後。
これを見て、何が起こっているのか理解することができました。

ここまできたところで、「MAGPIE_CACHE_AGE」で検索したら、同じ目にあっている方を発見しました。
もう少し早く発見できればよかった・・・。

MagpieRSSのキャッシュとConditional GETについて – F.Ko-Jiの「一秒後は未来」
F.Ko-Jiの「一秒後は未来」

WordPressのマルチサイトでユーザー追加時に500エラー

概要

マルチサイトでユーザーを追加したところ、ネットワーク管理者の画面から追加しても、各サイトから追加しても、新規の場合は500 Internal Server Errorになります。

エラーが出ていますが、ユーザーは登録されていました。
メールは管理者には届いているけれど、登録されたユーザには届きませんでした。

条件を整理して、何が原因かをつきとめて対応しました。

簡単にまとめると、こんな感じです。
Webサーバはさくらインターネット、メールサーバはGoogle Appsを利用しています。
ユーザが追加されると、管理者と本人にメールを出します。
Webサーバから同じドメイン名(マルチドメインで利用している場合はそのドメインも)を持つメールアドレスにメールを出すときに、DNSを参照せずに内部処理を行っていると思われます(ログ見ていませんが状況から)。
さくらのサーバ内には該当するメールアドレスが無いので、sendmailでエラーが出て、500 Internal Server Errorとなりました。

管理者のメールアドレスはGoogle Appsの管理外だったので、メールが届いていました。

目次

  1. サイト構成
  2. ユーザ登録するメールアドレスによって現象が異なる
  3. “Google Apps” “PHPMailer” “さくら”で調べてみると
  4. プラグインを入れる

1.システム構成

WordPress
3.1.3 マルチサイト(サブドメディレクトリ型、サブドメイン型の両方とも現象が出ました)
Webサーバ
さくらのレンタルサーバ スタンダードを独自ドメインで運用
ドメイン管理
お名前.com
メール
ユーザーとして追加したのはGoogle Apps,Gmail

2.登録するメールアドレスによって現象が異なる

Gmail(ドメインが@gmail.com)のメールアドレスや、携帯メールのアドレスを登録するときは、エラーは発生せずユーザー登録が完了し、登録されたアドレスにメールが届きました。

WordPressで作ったサイトのURLを「http://example1.com」として、メールアドレス「user@example1.com」をGoogle Appsで管理しているとすると、「user@example1.com」を登録するときに500 Internal Server Errorとなりました。

また、さくらのレンタルサーバ内で「http://example2.com」をマルチドメインとして管理していて、「user@example2.com」をGoogle Appsで管理しているとすると、WordPressで作ったサイト「http://example1.com」に「user@example2.com」を登録するときにも500 Internal Server Errorとなりました。

3.”Google Apps” “PHPMailer” “さくら”で調べてみると

こちらのページを見つけました。

PHPMailerでGmailのメール送信

確かに「dead.letter」に送信されなかったメールの情報が書き込まれています。

まず、wp-includes/pluggable.phpをエディタで開き、次のように修正します。

381行目あたりの$phpmailer->IsMail();を$phpmailer->IsSMTP();に変更します。

      中略

そして、wp-includes/class-phpmailer.phpを開き、165行目から始まるSMTP設定の変数を次のように変更します。

に従って修正すると、エラーが発生することなくユーザ登録が完了しました。
登録したメールアドレスにメールも届いてます。

Pleskでサーバ管理していたときも、確かにこういう現象が発生していました。
共有サーバなのでログを自分で見たりはできないし、サポートにも確認していませんが、恐らく似たようなことが起こっていると想像できます。

4.プラグインを入れる

とりあえずコアファイルをいじりましたが、アップグレードで戻ってしまうのを避けるため、プラグインを探しました。

Cimy Swift SMTP

情報源はこちら。

さくらインターネットのPHPでMail関数を使うとInternal Server Errorになってしまう

マルチサイトの場合、各サイトごとにプラグインを有効化して「設定 > Cimy Swift SMTP」で設定を行います。
ネットワークにユーザを追加する場合は、blogid=1のサイトのCimy Swift SMTP設定が適用されます。

WordPressマルチサイト機能を使ったサイトでモバイル対応

WordPressのマルチサイト機能を使っているサイトで、モバイル端末の対応を行うことになりました。
モバイル端末表示用のプラグインを、マルチサイト環境で導入している情報は非常に少なかったです。

WPtouch Proを使ってみました。
マルチサイトでWPtouch

それぞれ一苦労あったようですが、WPtouchは使うことができるようです。

他のプラグインはどうかなと思いつつ、多くを調べる余力はないので、こちらの記事でちょっと気になったWPTapも試すことにしました。

多数デバイスに対応させる事も可能なモバイル自動対応WordPressプラグイン・WPtap

目次

  1. サイト構成とマルチサイト化の形式
  2. 先にWPTapを試しました
  3. 次にWPtouchを試しました
  4. 携帯電話対応にKtai Styleを使うことにしました

1.サイト構成とマルチサイト化の形式

WordPressのマルチサイト化(ネットワークの作成)についてはこちらを参照。

サブディレクトリ型を採用しました。

親サイト  http://example.com
子サイト1 http://example.com/site1
子サイト2 http://example.com/site2

親サイトに投稿はありません。固定ページは2つあります。
親サイトは、子サイト1、子サイト2の投稿を加工したものや、固定ページへのリンクなどを表示しています。

WordPress 3.1.3、さくらのレンタルサーバ スタンダードで運用しています。

2.先にWPTapを試しました

WPTapプラグインをインストール、ネットワークでは有効化せず、各サイト(親サイト、子サイト1、子サイト2)で有効化して、とりあえずデフォルトのままで表示を確認しました。

見た目はよかったのですが、以下の2つの理由で採用を見送りました。

その1)プラグインを有効にすると、PCでサイトを見たときも切り替えFooterが出てしまう。

wptapの切り替えFooter避ける方法はあるかもしれませんが、その2)の理由もあるので深追いしませんでした。

その2)親サイトに見合った表示ができない。

親サイトは、子サイト1、子サイト2の投稿を動的に取得して表示しています。
親サイトに投稿を追加して、そこに子サイト1、子サイト2のリンクを表示するという方法も考えましたが、その1)の理由もあるので、採用をやめました。

おまけ)設定をいじっていると初期設定に戻れなくなる現象が

News Press > Mobile Devices の画面で、Current Mobile ThemeをSelect Mobile Themeから他のテーマに変えて保存すると、News Press > Theme Settings がメニューから消えます。

元に戻そうと、News Press > Mobile Devices の画面で、Current Mobile ThemeをSelect Mobile Themeに戻しても、News Press > Theme Settings は消えたままです。

wptap\admin\admin.phpの111行目あたりを修正します。

前 <option>Select Mobile Theme</option>

後 <option value=”News Press”>Select Mobile Theme</option>

3.次にWPtouchを試しました

WPtouchプラグインをインストール、ネットワークでは有効化せず、各サイト(親サイト、子サイト1、子サイト2)で有効化して、とりあえずデフォルトのままで表示を確認しました。

子サイトは問題ないようです。

親サイトは、モバイル端末用のTOPページを作成する方向で検討しました。

最初は、固定ページでモバイル端末用のTOPページを作成して、「ホームページリダイレクト」で指定しようとしました。
しかし、PC版で表示(モバイルテーマOFF)の際もモバイル端末用のTOPページが表示されるのでやめました。

結局、親サイトに投稿を追加して、そこに子サイト1、子サイト2のリンクを表示するようにしました。

4.携帯電話対応にKtai Styleを使うことにしました

WPtouchプラグインはあくまでもスマートフォン対策なので、携帯電話対応のためKtai Styleプラグインも導入しました。

携帯表示 > テーマ の「電話キャリア別テーマ」を設定するところで、

iPhone, Android 用 (Ktai Styleを使わない)

と設定します。

おまけ

wp_footer()を何らかの理由でコメントアウトしていると、切り替えメニューが出なくなるので注意です。

WordPressに入れたLightbox 2プラグインがIE8で機能していなかった

メインブラウザはChrome。
サイトチェックは最低限IE、Firefox、Chromeで行っています。
対象のサイトはこちら。

北の庭とごはん

Lightbox 2(2.9.2)はこちらからダウンロード。

Lightbox 2

リリース当初から割と最近まで、Lightbox 2プラグインはIE8でも機能していました。

昨日たまたまIE8でサイトを見たらzenbackが表示されていないのに気づき、Lightbox 2でエラーが出ていることが分かりました。そして、Lightbox 2をオフにしたら、zenbackは表示されました。

メッセージ: ‘style’ は Null またはオブジェクトではありません。 ライン: 33 文字: 6 コード:

zenbackをキーにして調べたら「jQueryを利用しているブログで、zenbackを設置する時のアドバイス」という情報に当たりましたが、Lightbox 2プラグインはjQueryベースではない模様。

単純に、Lightbox 2のエラーが出なければいいのではと思い、別のプラグインを探すことにしました。

参考にしたのはこちら。

WordPressにLightbox風プラグインを導入する

WP jQuery Lightbox(1.3.1)に変えました。
プラグインをWP jQuery Lightboxに変えただけで、IE8、Firefox、Chromeとも画像がLightbox風に表示されるようになりました。

Chromeでは「Close」が機能していなかったのも、直りました。

不具合のタイミングで思い当たるのは、WordPressのバージョンを3.0.x(枝番忘れました)から3.1.1にしたこと。

バージョンアップでエラーは出ていなかったので、細かい確認を怠っていました。

フォームデータをSTDINで取得できないケース

my $cgi = new CGI;
したら、その後フォームデータをSTDINで取得できなかった。
[取得できなかった方法]

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

$bufferの中身は空。

もちろんこの形式では取得可能。

my @params = $cgi->param();

また、my $cgi = new CGI;を削除したらSTDINで取得可能。

どちらかにせよということ?

さくらのレンタルサーバにて。