WordPress リビジョン(履歴)保存の回数制限・無効化を行う方法とバグについて

リビジョン管理

WordPressではコード上でリビジョン(記事の投稿履歴)の保存回数を制限したり、リビジョン管理を停止/無効化することができます。ただし、リビジョン数を1つ、または2つに制限した場合には注意が必要となります。

リビジョンシステムの過度な利用はwp_postsテーブルを肥大化させることに繋がり、サイトの表示速度の低下や、データベースの容量を圧迫する原因にもなります。投稿履歴への依存が少ないユーザは、リビジョンの保存回数の制限や停止を検討してみるのも良いでしょう。

目次

リビジョンを無効化する方法

リビジョンの管理を停止/無効化するには、wp-config.phpファイル内にWP_POST_REVISIONS定数を定義し、値をfalseに指定します。

// wp-config.php
define('WP_POST_REVISIONS', false); // 履歴を保存しない

ただし、自動保存用のリビジョン管理は通常通り機能し続けます(1記事に対して1つの履歴が使い回しされるためDBの肥大化を心配する必要はほとんどない)。

falseの代わりに0を指定することも可能です。WP_POST_REVISIONSが未定義の場合にはデフォルトのtrueないし-1と解釈され、すべての履歴が保存されます。

リビジョンの回数を制限する方法

リビジョンの数を制限するには、wp-config.phpファイル内にWP_POST_REVISIONS定数を定義し、値を1以上の整数値に指定します。

// wp-config.php
define('WP_POST_REVISIONS', 3); // 履歴の保存数を最大3つまでに制限する
リビジョン数を下げた場合、超過した分の既存のリビジョンはすべて削除されるため注意してください。必要に応じてデーターベースやテーブルのバックアップを行ってください。

保存数が上限に達した場合、古いリビジョンが随時に削除されます。

なお自動保存用のリビジョンはこれらの上限に含まれません。

ただしWordPress側のバグによって、自動保存用のリビジョンが上限に含まれてしまう場合があります(参考:WP_POST_REVISIONS を 2 に設定した場合の注意点)。

フィルターを用いて投稿ごとにリビジョン管理する方法

wp_revisions_to_keepフィルターを用いることにより、投稿ごとにリビジョン制限を行うこともできます。この場合はfunction.php側でフィルターを定義します。

add_filter('wp_revisions_to_keep', function ($num, $post) {
  return 3;  // 履歴の保存数を最大3つまでに制限する
  return 0;  // 履歴を保存しない
  return -1; // 履歴を常に保存する
  return $num; // デフォルトのリビジョン数
}, 10, 2);

$postには現在の投稿がWP_Post型のオブジェクトとして渡ってきます。デフォルトのリビジョン数$numWP_POST_REVISIONS定数の値を元に算出されます。WP_POST_REVISIONSfalseの場合は0, trueの場合は-1の値、それ以外では整数値(intval(WP_POST_REVISIONS))が渡ってきます。

WP_POST_REVISIONS を 1 に設定した場合の注意点

WP_POST_REVISIONS1を指定した場合、編集前の情報は履歴として保存されなくなってしまいます。

WordPressのリビジョン機構は編集履歴ではなく投稿履歴であり、編集前の情報を履歴として残すのではなく、投稿時の情報を履歴として残すという方式が採用されているためです。

つまり「aというタイトルの記事」を新規投稿した場合、「aというタイトルの履歴」が同時に保存されることになります。そして、タイトルを「abに変更し再投稿」を行った場合には、「abというタイトルの履歴」が新たに保存されることになります。ここでWP_POST_REVISIONS1に制限されていた場合、先ほどの「aというタイトルの履歴」は消失してしまいます。

wp_postsテーブルの更新イメージ

a というタイトルの記事を新規投稿

IDpost_titlepost_type
1apost投稿された記事のデータ
2arevision上記の履歴

aab に変更して再投稿

IDpost_titlepost_type
1abpostpost_titleが更新された
3abrevision上記の履歴を取り直す
WP_POST_REVISIONS = 1 なので以下の履歴は削除される
IDpost_titlepost_type
2arevision

よってWP_POST_REVISIONS1を指定した場合、編集前の情報は履歴として残らず、復元も行えないことになります。これでは履歴を取る意味がありません。もっとも、自動保存用のリビジョンへの復元は行えるため、本モードは現行リビジョンと自動保存用リビジョンの切り替え用の機能として用いることができます。

しかしそれではあまり意味がないため、WP_POST_REVISIONSの値は2以上、できれば3以上の値に設定する必要があります。

WP_POST_REVISIONS を 2 に設定した場合の注意点

WP_POST_REVISIONSの値が2に変更された環境で新規の自動保存が働いた場合、前回の履歴が消失してしまう危険性があります。初回に限り自動保存用の履歴もリビジョン制限の対象になるためです(おそらくバグ)。

というのも、再投稿時には通常の履歴と自動保存用の履歴の2つが登録されることになりますが、WP_POST_REVISIONS = 2の場合には前回の履歴が超過分として削除されてしまいます(ここで消失が起こる)。もっとも、次回以降の再投稿では自動保存用の履歴を含めて3つ分の履歴が保存されるようになります(これはバグではない)。

WP_POST_REVISIONS = 3を設定すれば、初回の自動保存用の履歴を考慮したより最善な履歴管理が行えます。

IDpost_titlepost_typepost_name
1abpostab
2arevision1-revision-v1まだ削除されない
3abrevision1-autosave-v1
4abrevision1-revision-v1

しかしこの場合はあくまで前回分の履歴の生存が保証されるだけであって、新規の自動保存が働いた際には前々回の履歴は超過分として削除されてしまいます(これもバグ)。

これらの消失問題は自動保存用のスクリプトを無効化することで対処が可能であると思われがちですが、自動保存は再投稿時のプレビュー機能を利用した際にも強制的に行われるため、根本的な問題の解決にはなりません。

WP_POST_REVISIONS に 2 が指定された際のバグとその挙動

WP_POST_REVISIONS = 2の場合、select * from wp_posts where ID in (2, 3, 4) order by ID ascの先頭行が削除対象の履歴となるため、ID = 2のレコードが削除されます。

IDpost_titlepost_typepost_name
1abpostab
2arevision1-revision-v1この履歴が削除される
3abrevision1-autosave-v1
4abrevision1-revision-v1

これによって編集前の履歴が消失しました。 この挙動は、削除対象のクエリー結果に自動保存用のレコードが含まれてしまっているために起こります。具体的には「クエリー結果の行数WP_POST_REVISIONS」(3 - 2)の結果が1となり、この一件分の履歴削除が働くためにID = 2のレコードが削除されてしまいます。

ちなみに、2回目以降の再投稿では、select * from wp_posts where ID in (3, 4, 5) order by ID ascの先頭行は自動保存用の履歴であるため、削除が回避されます。

IDpost_titlepost_typepost_name
1abcpostab
3abrevision1-autosave-v1自動保存用なので削除しない
4abrevision1-revision-v1
5abcrevision1-revision-v1

3回目以降は、ID in (3, 4, 5, 6)の先頭行と次の行が削除対象となり、ID = 4の履歴が正常に削除されます。ID = 3は例によって自動保存用の履歴であるため、削除が回避されます。

IDpost_titlepost_typepost_name
1abcdpostab
3abrevision1-autosave-v1自動保存用なので削除しない
4abrevision1-revision-v1削除される
5abcrevision1-revision-v1
6abcdrevision1-revision-v1
広告