
WordPress 4.7から「post_password_required」というアクションフィルターが追加されました。これを使って 1つしか設定できなかった パスワード保護ページの 投稿パスワードを複数登録して使えるようにできそうです。
WordPressでは 投稿にパスワードを設定すると 投稿ページは内容は表示されずに パスワード入力フォームが出てきます。
パスワードを入力して「確定(送信)」すると パスワードはwp-login.phpへ送られ クッキーに保存されてから投稿ページに戻され(リダイレクト)ます。
投稿ページでは クッキーのパスワードを照合して、合っていれば 投稿内容を表示します。
ここでは照合の中にある「post_password_required」フィルターを使って 全ての投稿パスワード記事 共通の投稿パスワードを登録して照合する簡易版を作りました。
今迄のパスワード保護ページで投稿パスワードがバラバラでもこの Tips を使えば 共通の投稿パスワード として使えます。
投稿ごとに個別の投稿パスワードを複数設定したい場合は以下の記事を参考にしてください。
「WordPress パスワード保護ページの 投稿パスワード を「投稿別」に複数使えるようにする」
スポンサードリンク
コード
管理画面の設定→共通投稿パスワードで全てのパスワード保護の記事で有効な パスワードを複数設定します。

この仕組みを使うと、後で投稿パスワード入りの記事を追加しても自動で「共通 投稿パスワード」で閲覧する事ができます。
また期限チェックも追加しています。パスワードが合っていても期限が過ぎていたらNGになります。
※共通投稿パスワードを使わない投稿を設定できるようにもしています。
以下のコードを my-plugin.php に張り付けてみてください。
/**
* 共通 投稿パスワード
*
* @since WordPress 4.7.0
* License: GPLv2 or later
*/
if( is_admin() ){
new nendebcom_Common_Multi_Post_Password();
}
class nendebcom_Common_Multi_Post_Password {
/**
* Start up
*/
function __construct() {
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
}
/**
* Add options page
*/
function admin_menu () {
add_options_page( 'common_multi_post_password', '共通投稿パスワード', 'edit_posts', __FILE__, array( $this, 'form' ) );
}
/**
* Saves Multi Post Password.
*/
function save_common_multi_post_password() {
require_once ABSPATH . '/wp-includes/pluggable.php';
// Check if our nonce is set.
if ( !isset( $_POST[ 'admin_nendebcom_multi_postpass_nonce' ] ) ) {
return;
}
// Verify that the nonce is valid.
if ( !wp_verify_nonce( $_POST['admin_nendebcom_multi_postpass_nonce'], 'admin_nendebcom_multi_postpass_nonce' ) ) {
return;
}
// Make sure that it is set.
if ( !isset( $_POST['max_id'] ) ) {
return;
}
// 登録パスワード数
$max_id = isset( $_POST['max_id'] ) ? $_POST['max_id'] : 0;
$multi_postpass_data = array();
$j = 0;
for ( $i = 0; $i <= $max_id; $i++ ) {
$postpass_kigen = isset( $_POST[ 'postpass_kigen_' . $i ] ) ? sanitize_text_field( $_POST[ 'postpass_kigen_' . $i ] ) : '';
$postpass_pass = isset( $_POST[ 'postpass_pass_' . $i ] ) ? sanitize_text_field( $_POST[ 'postpass_pass_' . $i ] ) : '';
$postpass_memo = isset( $_POST[ 'postpass_memo_' . $i ] ) ? sanitize_text_field( $_POST[ 'postpass_memo_' . $i ] ) : '';
$postpass_date = isset( $_POST[ 'postpass_date_' . $i ] ) ? sanitize_text_field( $_POST[ 'postpass_date_' . $i ] ) : current_time( 'timestamp' );
// Postpass Max255文字
$postpass_pass = substr( $postpass_pass, 0, 255 );
if ( $postpass_pass ) {
$multi_postpass_data[ $j ][ 'postpass_kigen' ] = $postpass_kigen;
$multi_postpass_data[ $j ][ 'postpass_pass' ] = $postpass_pass;
$multi_postpass_data[ $j ][ 'postpass_memo' ] = $postpass_memo;
$multi_postpass_data[ $j ][ 'postpass_date' ] = $postpass_date;
$j++;
}
}
// Update the meta field in the database.
update_option( 'multi_postpass', $multi_postpass_data );
// 除外投稿パスワード
$postpass_exclude_post = isset( $_POST['postpass_exclude_post'] ) ? $_POST['postpass_exclude_post'] : '';
update_option( 'postpass_exclude_post', $postpass_exclude_post );
return '保存しました。';
}
//プラグイン設定フォーム
function form() {
$save_valu = $this->save_common_multi_post_password();
echo '<div class="wrap">';
echo '<h1 class="wp-heading-inline">共通投稿パスワード</h1>';
echo '<hr class="wp-header-end">';
if( $save_valu ){
echo '<div id="setting-error-settings_updated" class="updated settings-error notice is-dismissible">';
echo '<p><strong>' . $save_valu . '</strong></p>';
echo '</div>';
}
echo '<form method="post" action="">';
// Add a nonce field so we can check for it later.
wp_nonce_field( 'admin_nendebcom_multi_postpass_nonce', 'admin_nendebcom_multi_postpass_nonce' );
// デフォルトパスワード期限 ( 今日から3カ月後 )
$kijitsu = date( 'Y/m/d', strtotime( date( 'Y/m/d', strtotime( date_i18n( 'Y/m/d' ) . '+3 month' ) ) . ' -1 day' ) );
// 投稿パスワード取得(配列)
$multi_postpass_data = maybe_unserialize( get_option( 'multi_postpass', false ) );
if ( !$multi_postpass_data ) {
$multi_postpass_data = array();
}else{
//登録日でソート
foreach ( $multi_postpass_data as $key => $value ){
$key_id[$key] = $value['postpass_date'];
}
array_multisort ( $key_id , SORT_DESC , $multi_postpass_data );
}
// 登録パスワード数
$tmp_max_id = count( $multi_postpass_data );
echo '<input type="hidden" name="max_id" value="' . $tmp_max_id . '">';
// CSS 表示テーブル用
?>
<style type="text/css">
div#multi_postpass {
background-color: #fff;
padding: 10px;
margin: 30px 0 0;
}
table.multi_postpass_table{
width: 100%;
}
table.multi_postpass_table tr.header {
background: #f3f3f3 none repeat scroll 0 0;
}
table.multi_postpass_table th {
text-align: left;
padding: 3px 5px;
}
table.multi_postpass_table td input[type="text"] {
width: 100%;
}
table.multi_postpass_table td.kigen {
width: 15%;
}
table.multi_postpass_table td.pass {
width: 30%;
}
table.multi_postpass_table td.memo {
width: 40%;
}
table.multi_postpass_table td.date {
width: 15%;
text-align: center;
}
</style>
<?php
// 表示テーブル
echo '<div id="multi_postpass">';
echo '全ての投稿パスワード記事で有効な ユーザー個別のパスワードを設定します。';
echo '<table class="multi_postpass_table">';
echo '<tr class="header">';
echo '<th>期限</th>';
echo '<th>パスワード</th>';
echo '<th>メモ</th>';
echo '<th>登録日</th>';
echo '</tr>';
//新規
echo '<tr>';
echo '<td class="kigen"><input type="text" name="postpass_kigen_' . $tmp_max_id . '" value="' . $kijitsu . '" size="10" autocomplete="off"></td>';
echo '<td class="pass" ><input type="text" name="postpass_pass_' . $tmp_max_id . '" value="" size="20" autocomplete="off"></td>';
echo '<td class="memo" ><input type="text" name="postpass_memo_' . $tmp_max_id . '" value="" size="60" autocomplete="off"></td>';
echo '<td class="date">新規</td>';
echo '</tr>';
//修正・削除
if ( !empty( $multi_postpass_data ) ) {
$i = 0;
foreach ( $multi_postpass_data as $data ) {
echo '<tr>';
echo '<td class="kigen"><input type="text" name="postpass_kigen_' . $i . '" value="' . $data[ 'postpass_kigen' ] . '" size="10"></td>';
echo '<td class="pass" ><input type="text" name="postpass_pass_' . $i . '" value="' . $data[ 'postpass_pass' ] . '" size="20"></td>';
echo '<td class="memo" ><input type="text" name="postpass_memo_' . $i . '" value="' . $data[ 'postpass_memo' ] . '" size="60"></td>';
echo '<td class="date" ><input type="hidden" name="postpass_date_' . $i . '" value="' . $data[ 'postpass_date' ] . '">' . date('Y/m/d', $data[ 'postpass_date' ] ) . '</td>';
echo '</tr>';
$i++;
}
}
echo '</table>';
echo ' ※パスワードを 空欄にして保存すると、その行は削除されます。';
echo '<br>';
echo '<br>';
// 除外投稿パスワード取得
$postpass_exclude_post = get_option( 'postpass_exclude_post', false );
echo '<table class="multi_postpass_table">';
echo '<tr class="header">';
echo '<th>除外共通投稿パスワード</th>';
echo '</tr>';
echo '<tr>';
echo '<td><input type="text" name="postpass_exclude_post" value="' . $postpass_exclude_post . '" autocomplete="off"></td>';
echo '</tr>';
echo '</table>';
echo ' ※共通投稿パスワードを使わない投稿IDを入力してください。( post_id カンマ区切り )';
echo '<p class="submit"><input type="submit" name="submit" id="submit" class="button-primary" value="変更を保存" /></p>';
echo '</div>';
echo '</form>';
echo '</div>';
}
}
/**
* オプションに入れた パスワードで認証する
* Filters whether a post requires the user to supply a password.
*
* @since WordPress 4.7.0
* post-template.php
*
* @param bool $required Whether the user needs to supply a password. True if password has not been
* provided or is incorrect, false if password has been supplied or is not required.
* @param WP_Post $post Post data.
* License: GPLv2 or later
*/
function nendebcom_common_multi_post_password_required( $required, $post ) {
if ( !$required ) {
return $required;
}
// パスワードデータ読込
$multi_postpass_data = maybe_unserialize( get_option( 'multi_postpass', false ) );
// 除外投稿パスワード取得
$postpass_exclude_post = get_option( 'postpass_exclude_post', false );
$postpass_exclude_post_array = explode( ',', $postpass_exclude_post );
$hasher = new PasswordHash( 8, true );
// 追加照合
$hash = isset( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) ? wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) : '';
if ( 0 !== strpos( $hash, '$P$B' ) ) {
$required = true;
} else {
if ( !empty( $multi_postpass_data ) ) {
// パスワードチェック
foreach ( $multi_postpass_data as $passdata ) {
if ( $hasher->CheckPassword( $passdata[ 'postpass_pass' ], $hash ) ) {
// 除外投稿ID
foreach ( $postpass_exclude_post_array as $exclude_post_id ) {
if( $exclude_post_id == $post->ID ){
return $required;
}
}
//期限チェック
if ( strtotime( date_i18n( "Y/m/d" ) ) <= strtotime( $passdata[ 'postpass_kigen' ] ) ) {
return false;
}
}
}
}
}
return $required;
}
add_filter( 'post_password_required', 'nendebcom_common_multi_post_password_required', 11, 2 );
※このフォームを触れる権限は「edit_posts」にしてますが、変更したい場合は add_options_pageの所で変更してください。
※投稿パスワードフォームのいちばん上の行が新規登録用になります。
※消したいパスワードがある場合、該当のパスワードを 空欄にして保存すると、その行は削除されます。
※デフォルトパスワード期限は使う用途で変更してください。
※WordPressの標準の投稿パスワード設定は必要です。これをしないと パスワード保護機能自体 動作しません。
あとがき
ここまで出来たら、運用しだいでいろいろなケースに対応できそうです。
また、WordPressの標準の投稿パスワードは、全て同じパスワードをいれて、スーパーユーザー用とか確認用とかに使ったらどうでしょうか?
そんな場合の全て同じパスワードを簡単に設定できる方法はこちらにあります。
「パスワード保護ページの 投稿パスワード を 一括編集できるようにする」
投稿ごとに個別の投稿パスワードを複数設定したい場合は以下の記事を参考にしてください。
「WordPress パスワード保護ページの 投稿パスワード を「投稿別」に複数使えるようにする」
あまりパスワード数が多くなると、使いにくくなりますので 実用的に変更しないといけません。
追加用の投稿パスワード情報は投稿ごとに 1つのカスタムフィールドにまとめて入るようにしてます。
もしかしたら パスワード情報を 新しい別のテーブルに持たせるようにした方が安心かもしれません。
参考
post_password_required | Hook | WordPress Developer Resources
https://developer.wordpress.org/reference/hooks/post_password_required/
管理メニューの追加 – WordPress Codex 日本語版
https://wpdocs.osdn.jp/%E7%AE%A1%E7%90%86%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E3%81%AE%E8%BF%BD%E5%8A%A0
関数リファレンス/add options page – WordPress Codex 日本語版
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_options_page
ユーザーの種類と権限 – WordPress Codex 日本語版
https://wpdocs.osdn.jp/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E7%A8%AE%E9%A1%9E%E3%81%A8%E6%A8%A9%E9%99%90