見出し画像

Wordpressのプラグイン「WP-Members」で新規投稿ページ作成時にデフォルトで「コンテンツを保護」の状態にする方法

「WP-Members」を導入して、WordPressのアクセス制限を行う

WordPressで作成したコンテンツにアクセス制限を行う際、「WP-Members」は導入が手軽な割に権限管理などがし安く便利なプラグインだ。 しかし、アクセス制限をするには、固定ページや投稿ページを作成する際、プラグインが表示する以下の箇所で、ラジオボタンやチェックボックスを切り替える必要がある。

※日本語表示の場合。「WP-Members」のデフォルトは英語表示になっている。
WordPressの場合、ページの作成をユーザーに行わせることも多いが、 このラジオボタンはデフォルトが「いいえ、このコンテンツを保護しません。」になっている。 その為、ユーザがページ作成時にラジオボタンを変更し忘れていると、制限をかけるべきコンテンツが全体に公開されてしまう……ということになり安い。 これを投稿時のマニュアルを作成して「気をつけてください」とだけ言って済ませるのはリスクがある為、できればデフォルトで「はい、コンテンツを保護します。」の状態にしておきたい。

プラグインのクラスファイルを編集する

調べると、「コンテンツを保護します」のラジオボタンや権限管理のチェックボックスは「WP-Members」プラグインの以下のクラスファイルで管理している。

  • ファイルパス:/(wordpressのインストールディレクトリ)/wp-content/plugins/simple-membership/classes/class.simple-wp-membership.php ファンクション名:inner_custom_box()

ファンクション内を見ると、ラジオボタンの記述は以下の箇所。

public function inner_custom_box() {
    global $post, $wpdb;
    $id = $post->ID;
    // Use nonce for verification
    $is_protected = SwpmProtection::get_instance()->is_protected($id);
    echo '<input type="hidden" name="swpm_noncename" id="swpm_noncename" value="' .
    wp_create_nonce(plugin_basename(__FILE__)) . '" />';
    // The actual fields for data entry
    echo '<h4>' . __("Do you want to protect this content?", 'swpm') . '</h4>';
    echo '<input type="radio" ' . ((!$is_protected) ? 'checked' : "") .
    '  name="swpm_protect_post" value="1" /> No, Do not protect this content. <br/>';
    echo '<input type="radio" ' . (($is_protected) ? 'checked' : "") .
    '  name="swpm_protect_post" value="2" /> Yes, Protect this content.<br/>';

Wordpressの投稿ページのIDを元に、現在の登録状況に応じてチェック状態を変更するというシンプルな処理だが、新規投稿ページを作成する場合に、「コンテンツを保護します(Yes, Protect this content.)」にチェックさせるには、少し厄介である。 今、新規投稿ページを作成する処理であるかどうかは、IDだと判別が付かないからだ。 Wordpressでは新規投稿ページの処理を開いた段階で新規にIDが割り振られるため、編集段階なのか、新規投稿段階なのかを判別する処理を記述する必要がある。
……やや強引だが、URLを元に判別するのが一番手っ取り早そう。 投稿ページでも、固定ページでも、新規投稿時はWordpressのURLが「post-new.php」になるので、

$current_uri = $_SERVER['REQUEST_URI'];
if (strpos($current_uri, 'post-new.php') !== false) {
     $is_protected = true;
}

という処理を「inner_custom_box()」のラジオボタンを記述する処理の直前に追加。 これで、投稿ページ( 'post-new.php')では「コンテンツを保護します」がデフォルトでチェックされる。

権限管理のチェックボックスもデフォルトでonにする

権限管理のチェックボックスも同様にURLを元にすれば、新規投稿ページのみの処理を行うことができる。 処理が記述されているのはラジオボタンと同じく、inner_custom_box()内の以下の箇所。

$levels = $wpdb->get_results($query, ARRAY_A);
foreach ($levels as $level) {
    echo '<input type="checkbox" ' . (SwpmPermission::get_instance($level['id'])->is_permitted($id) ? "checked='checked'" : "") .
    ' name="swpm_protection_level[' . $level['id'] . ']" value="' . $level['id'] . '" /> ' . $level['alias'] . "<br/>";
}

登録されている権限の数に応じて配列で取得してきているので、投稿ページのhtmlのソースを元に、$level['id']の値を確認し、foreach文内で、デフォルトでチェックしたいボックスの値の時だけ、チェック状態になるようにすれば良い。
上の画像の「管理者」のチェックボックスは$level['id']の箇所の値が2であったので、

if (strpos($current_uri, 'post-new.php') !== false and $level['id'] == 2) {    echo '<input type="checkbox" ' . "checked='checked'"  .
    ' name="swpm_protection_level[' . $level['id'] . ']" value="' . $level['id'] . '" /> ' . $level['alias'] . "<br/>";
} else {
    echo '<input type="checkbox" ' . (SwpmPermission::get_instance($level['id'])->is_permitted($id) ? "checked='checked'" : "") .
    ' name="swpm_protection_level[' . $level['id'] . ']" value="' . $level['id'] . '" /> ' . $level['alias'] . "<br/>";
}

というif文の処理にすれば、新規投稿ページでのみ、デフォルトで管理者のチェックボックスをonにできる。

やや強引だが、ユーザに投稿させて、うっかり保護状態にしていないページを投稿される危険よりはマシだろう。 プラグインの記述を変更するので、念のため記述を変更する前にバックアップを忘れずに。

お知らせ

電巧社ではセキュリティ分野専門のブログも公開しています。ゼロトラストセキュリティを始めとした、ランサムウェアへの対処法等を紹介しています。こちらもよろしくお願いします。