web-dev-qa-db-ja.com

ログイン画面で入力したパスワードに基づいてパスワード付きページにリダイレクトする方法

だから私は ピーターのログインリダイレクト のようなものを探していますが、少し異なります。私は写真のWebサイト用のクライアントポータルを構築したいと思います、そして私はクライアントのためにカスタム投稿タイプを追加し、CPTに必要な追加機能のすべてを追加するために高度なカスタムフィールドを使うことが最善の方法を考え出しました。新しいクライアントが追加されると、そのクライアントのアクセスページに新しいURLが作成されます。簡単そうです。

それから、各ページをパスワードで保護し、そのパスワードをクライアントに送信するだけです。これはすべて素晴らしいことですが、サイトのメインナビゲーションにある「ログイン」ボタンも一緒に付けたいと思います。誰かがこのボタンをクリックしたとき、私たちが彼らに電子メールで送ったパスワードを入力できるパスワードフォームを彼らに提示して欲しいです。入力したパスワードに基づいて、適切なCPTページにリダイレクトされます。誰が私がこれに取り組むことができるかについて何か考えがありますか?パスワードに基づいて投稿を取得するために何らかの方法でクエリを実行できると思いましたが、DBで使用されている暗号化がそれを可能にするかどうかはわかりません。任意の洞察力は大歓迎です。

私は自分の質問に答えました。これは私が必要としていたものとほぼ同じ機能を果たすプラグインですが、カスタム投稿タイプにも同じ機能が必要でした。

スマートパスワード付きページ

私はただプラグインを修正し、個人的な使用のために私自身のものを作りました。

便利に編集する:

このプラグインにはPHPファイルが1つだけ含まれています。このファイルには、3つの関数を含む "smartPWPages"という名前の単一クラスがあります。 "process_form"関数内には、get_pages関数への呼び出しがあります。バージョン3.8.1では、プラグインはそのままでは動作しなかったので、get_pages呼び出しから "child_of"と "parent"引数を削除しました。これらの引数を削除した後、プラグインは機能しますが、それはページだけです。カスタム投稿タイプで機能するようにするには、 "post_type"引数を "page"ではなくカスタム投稿タイプに変更するだけです。

これらのマイナーな調整により、カスタム投稿タイプを使用してクライアントポータルを設定できました。カスタム投稿タイプでは、入力されたパスワードに基づいてユーザーが適切な領域にリダイレクトされる単一のログインページがあります。私はプロジェクト管理システムなどのような項目のためにこれのための多くの用途を見ることができました。間違いなく便利なプラグインです。

これは私が思いついた解決策で、データベースにすでに存在する情報に依存しています。

バックグラウンド

パスワードで保護された各投稿は、(wp_posts列の)post_passwordテーブルにプレーンテキストでパスワードを格納します。パスワードを割り当てられた投稿をdbに問い合わせて、それに基づいて投稿情報を取得します。そこから、パスワードで保護された投稿にリダイレクトできます。

仮定/制約

OPはクライアントが彼らの特別なパスワードを入力するためにカスタムログインフォームが使用されるであろうと述べました。私は、フォームが作成され、すでにプレーンテキストであるため、パスワードを送信するためにGETリクエストを使用できると仮定しています。

OPはまた、投稿/ページを保護する各パスワードは一意であると述べました。私は、この答えとは別に固有のパスワードが生成されると考えています。

使い方

client_keyというクエリ文字列が(フォームのGETまたはリンクを通じて)送信され、get_query_var()を使用してチェックされます。存在する場合は、wp_postsと同じパスワードが設定されている最初の投稿のclient_keyテーブルを確認し、その行をオブジェクトとして返します。

健全性チェック:オブジェクトが作成されたら、JavaScript関数で使用するためにいくつかの変数を作成します。

script要素をDOMにエコーして、wp-login.phpに対してPOST関数を実行します。これは、パスワードで保護されたページに初めてアクセスしたときに通常発生するフォーム送信を模倣しています。そこでは、クライアントは投稿コンテンツを見るためのパスワードの入力を求められ、それが与えられると、コンテンツへの将来のアクセスを許可するためにクッキーが作成されます。この関数は舞台裏で同じフォーム送信を行い、適切な投稿にリダイレクトします(GUIDに基づいて)。

最後に、wp_headが起動されたとき(jQueryが[通常]ロードされたとき)、サイトのフロントエンドでのみ関数を実行してください。

コード

<?php
/**
 * Add our custom query string to the global query_vars.
 *
 * @param array $vars The global vars used throughout WP.
 *
 * @return array
 */
function wpse134962_add_query_vars_filter( $vars ) {
    $vars[] = 'client_key';

    return $vars;
}

add_filter( 'query_vars', 'wpse134962_add_query_vars_filter' );

/**
 * Redirect to a password-protected page based on the query string.
 *
 * If client_key is passed in the query string, check the database for a post that
 * has a password assigned that equals the client_key. If one is found, submit the
 * login form to create the cookie that allows entry, then redirect to the post.
 */
function wpse134962_password_redirect() {
    $client_key = get_query_var( 'client_key' ) ? get_query_var( 'client_key' ) : '';

    if ( ! empty( $client_key ) ) {
        /** @var wpdb $wpdb */
        global $wpdb;
        $query          = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_password = %s", $client_key );
        $password_posts = $wpdb->get_row( $query );

        if ( isset( $password_posts ) ) {
            $post_id   = $password_posts->ID;
            $login_url = site_url( 'wp-login.php' );

            echo <<<HTML
<script>
jQuery(function() {
var postURL = "$login_url?action=postpass",
    postData = {
        post_password: "$client_key"
    },
    postRedirect = function() {
        document.location = "{$password_posts->guid}";
    };
jQuery.post( postURL, postData, postRedirect() );
})();
</script>
HTML;

        }
    }

}

if ( ! is_admin() ) {
    /** Only fire on the front end of the site. */
    add_action( 'wp_head', 'wpse134962_password_redirect' );
}
2
Morgan Estes