2

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.

4
  • 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? Commented Feb 17, 2014 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. Commented Feb 17, 2014 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? Commented Feb 17, 2014 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 Commented Feb 17, 2014 at 21:20

2 Answers 2

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' );
}
0

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.

4
  • 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.
    Commented Feb 17, 2014 at 21:28
  • Done! Hopefully that's a bit more helpful. Commented Feb 17, 2014 at 21:37
  • @ThoughtSpaceDesigns I've looked at this plugin, but does it still work with the latest version of WP, it looks like it hasnt been updated for 2 years...?
    – Dano007
    Commented Feb 12, 2017 at 10:11
  • I'm honestly not sure, but you could download it and try making the modifications I specified above to see if it does work. If you enable debugging in your wp-config.php, you should see any issues that crop up printed out to the screen. Commented Feb 13, 2017 at 14:22

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