Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

So I'm looking for something like peter's login redirect, but slightly different. I want to build a client portal for a photography website, and I figured the best way would be to add a custom post type for clients and use advanced custom fields to add all of the extra functionality needed for the CPT. When a new client is added, a new URL will be created for the client's access page. Seems simple.

Then, we can just password protect each page and send the password to the client. This is all great, however I also want to accompany this with a "login" button in the site's main navigation. When someone clicks this button, I want them to be presented with a password form where they can enter the password we sent them in the email. Based on the password they enter, they'll be redirected to the appropriate CPT page. Anyone have any ideas on how I can go about this? I assumed I could somehow run a query to pull posts based on password, but I'm not sure if the encryption used in the DB would allow for that. Any insight would be greatly appreciated.

share|improve this question
    
Is the password unique to the page, or to the client? Will you have multiple passwords that can access a specific page, or does everyone get the same password for the page? –  morganestes Feb 17 at 20:49
    
Only one password per page, and each password will be unique so it can be used as the identifier for which to serve the correct page. The trick is that the page will be password protected, and after the redirect happens, I'll need to somehow pass the value entered on the login page to the second one, that way the client doesn't have to enter their password twice. –  Thought Space Designs Feb 17 at 20:51
    
Okay, a couple of more clarifying questions: is each client a registered user on the site (with info stored in wp_users)? I'm picturing a scenario where they have a regular login from WP to access the site, but a secondary password/key to access their page (via redirect from the login button in main nav). Is that close? –  morganestes Feb 17 at 21:17
    
@morganestes no, there would be no users for the clients. I would just create a custom post type and each user essentially gets a password protected page. When they put their password in the login screen, it redirects to the page with that password. I found an old plugin that does it but no longer works. I'm sifting through the code now. Here's what I'm looking for: wordpress.org/plugins/smart-passworded-pages –  Thought Space Designs Feb 17 at 21:20

2 Answers 2

Here's the solution I came up with that relies on the info already present in the database.

Background

Each password-protected post stores the password in plaintext in the wp_posts table (in the post_password column). We can use that to query the db for any posts that have that password assigned and get the post info based on that. From there, we can redirect to the password-protected post.

Assumptions/constraints

The OP stated that a custom login form would be used for clients to enter their special password. I'm assuming that form is created and can use a GET request to send the password since it's already plaintext.

The OP also stated each password protecting the post/page would be unique. I'm assuming that unique password is generated separately from this answer.

How it works

A query string of client_key is sent (either through the GET of the form, or through a link) and checked using get_query_var(). If it's present, check the wp_posts table for the first post that has a password set that equals the client_key and return the row as an object.

Sanity check: if object has been created, create a couple of variables to use in our JavaScript function.

Echo a script element into the DOM that will run a POST function to wp-login.php. This mimics the form posting that would normally happen when a password-protected page is visited for the first time. There, the client would be prompted for the password to view the post content, and once it was given a cookie is created to allow future access to the content. This function does the same form submission behind the scenes, the redirects to the appropriate post (based on GUID).

Finally, only run the function on the front-end of the site, when wp_head is fired (when jQuery is [usually] loaded).

The code

<?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' );
}
share|improve this answer
up vote 0 down vote accepted

I answered my own question. Here's a plugin that does almost exactly what I needed, but I needed the same functionality on custom post types:

Smart Passworded Pages

I just modified the plugin and made my own for personal use.

Editing for usefulness:

This plugin contains only one PHP file. In this file is a single class by the name of "smartPWPages" that contains 3 functions. Within the "process_form" function is a call to the get_pages function. In version 3.8.1, the plugin didn't work out of the box, so I removed the "child_of" and "parent" args from the get_pages call. After removing these args, the plugin works, but only for pages. In order to make it work for a custom post type, you can simply change the "post_type" arg to your custom post type instead of "page".

These minor tweaks enabled me to set up a client portal using a custom post type, which has a single log in page where users are redirected to their proper area based on the password entered. I could see many uses for this for items such as project management systems and the like. Definitely a useful plugin.

share|improve this answer
3  
Perhaps you can share the bit of code you are modifying to make the plugin work for Custom Post Types in your answer so this particular question is useful for other people? –  Stephen S. Feb 17 at 21:28
    
Done! Hopefully that's a bit more helpful. –  Thought Space Designs Feb 17 at 21:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.