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