WordPressの「投稿」画面を使わないで、別のシステムから直接SQL文を発行して記事をぶっこむ仕様のWebアプリを製作中。
本題の前に、WordPressの主な記事ステータスについてご説明します。
WordPressの記事ステータス
記事ステータスとはつまりその記事がどのような状態で保存されているか、ということです。
主なものを紹介すると、
- 下書き(draft)
- 公開中(publish)
- 予約投稿(future)
- ゴミ箱(trash)
が代表的なところです。
他には
- レビュー待ち(pending)
- 自動保存(auto-draft)
- 非公開(private)
- リビジョン(inherit)
があります。
さて、今回開発していたWebアプリでは、あえてpublishedではなく、futureで記事を登録していました。
なぜかというと記事の公開時にTwitter連携をしていたのですが、最初からpublishedで登録すると、Twitter連携アプリが作動する「記事公開時フック」を通らないので、Twitterに記事が配信されなかったからです。
そこでわざと予約投稿にして、公開はWordPress側にさせることでフックを通そう、という算段です。
しかし、予約登録まではうまくいくものの、公開予定時間になってもwp-cronが作動せず、「予約投稿の失敗」になってしまう。
WordPressの予約投稿のメカニズム
未来の日付で記事が投稿された場合、WordPressの記事ステータスが「future」になります。
この状態で公開日時以降にそのWordPressのどこかにアクセスが有った場合、wp-cronが作動して記事の公開処理が行われます。
cronと言ってもサーバーで時限処理をするcronと違って、WordPressにアクセスされた時に日時を持って公開判定をするので、擬似的なcronといえるでしょう。
しかし、予約投稿には
・記事の日付
・記事のステータス
以外にも、DB上では情報の更新がありました。
今回WordPress上から投稿した時と何が違うのか調べてみると、単純に記事の投稿時刻とステータスだけではなく、wp_optionsの中の「cron」というテーブルに予約動作に関する情報が登録されていたのでした。
wp-optionsのcronを調べてみる
中をのぞいてみると、このレコードは記事予約の他にはakismetのスパム削除スケジュールなど、WordPressが扱う予約動作全般の情報を保存しておくものでした。
で、今回の予約記事に関しては
i:1368027884;
a:1:{s:19:”publish_future_post”;
a:1:{s:32:”2b1da4ca66a51f7e26369cbe52edd54f”;
a:2:{s:8:”schedule”;
b:0;
s:4:”args”;
a:1:{i:0;
i:567;
という情報が増えていました。
publish_future_postはこの予約動作の種類を、最後のi:567は記事IDを示している、といった程度は分かるのですが、「2b1da4ca66a51f7e26369cbe52edd54f」などはどうもWordPressが乱数を発生させて割り当てているようで、これを解析して再現するのは骨が折れそうです。
その労力を考えると、素直にWordPressのXML-RPC投稿を利用したり、Twitterの投稿アプリを追加開発したりしたほうが良さそうな気がします…。
普通に予約投稿が失敗する場合
こういうなにか特別なことをしてるわけではなく、普通に運用しているはずのWordPressで予約投稿がうまくいかない場合は、こちらの記事が参考になるかと思います。
WordPressの予約投稿が失敗する件の解決方法