1

I have a shortcode which "wraps" <pre> and <code> content in a password array. This was created a while back and I'm struggling on how to add a cookie or some sort of session handler to this setup so that a user with a password doesn't have to re-enter the password each and every time during a certain time frame.

As of right now, the user has to enter the password on each post to view the content.

I've looked into the setcookie but I do not understand how to incorporate that with the code I'm using (the code was not written by me and the developer is gone). I'm just the CSS designer of the site, trying to make sense out of this.

I understand that it should be something like this?

$cookie_name = "mycookie";
$cookie_value = $result; 
setcookie($cookie_name, $cookie_value,time()+3600*24,COOKIEPATH, COOKIE_DOMAIN);

This is the full code that's currently in use:

add_filter( 'the_content', 'wrap_code_in_shortcode' , 9 );
function wrap_code_in_shortcode($content) {

    $content = preg_replace('/(<pre[^>]*>\s*<code[^>]*>)/',"[protected_content]$1", $content);
    
    $content =  preg_replace('/(<\/code>\s*<\/pre>)/', "$1[/protected_content]", $content);

    return $content;
}

add_shortcode( 'protected_content', 'protected_password_content' );
function protected_password_content( $atts, $content=null ) {

    if (in_array(@$_REQUEST['password'], array('password'))){
        $return = do_shortcode($content);

    } else {

        $return = '
        <span>To view this section, enter your access code.</span><br>
            <form action="" method="post">
            <input style="display:block; width: 69%; height: 50px; margin-right: 1%; padding: 0px; float: left; border:1px solid blue;border-radius:3px;" type="text" placeholder="&#32;&#32;&#32;Access Code Here" name="password">
            <input style="display:block; margin: 0px;  width: 30%; height: 50px; padding: 0px;" type="submit" value="Show Content">
            </form>';
        }
    return $return;
}

1 Answer 1

0

Welcome to WordPress Development StackExchange site! In general you understand everything right, but there can be one important caveat: if some page content like page header, navigation menu, etc is already sent to the user, a try to set cookie from PHP script will give a following error: "Cannot modify header information – headers already sent by...". To avoid it you can add some javascript to your form and set a cookie from this javascript. Lets try the following code:

function protected_password_content( $atts, $content=null ) {

    // if password is sent via posting form, try to use it first
    // next try to get password from the cookie
    $userpass = isset( $_REQUEST['password'] ) ? $_REQUEST['password'] : ( isset( $_COOKIE['userpass'] ) ? $_COOKIE['userpass'] : NULL );

    if ( in_array( $userpass, array('password') ) ) {
        $return = do_shortcode($content);
    } else {
        $return = '
            <span>To view this section, enter your access code.</span><br>
            <form action="" method="post" onsubmit="putCookie(this)">
            <input style="display:block; width: 69%; height: 50px; margin-right: 1%; padding: 0px; float: left; border:1px solid blue;border-radius:3px;" type="text" placeholder="&#32;&#32;&#32;Access Code Here" name="password" id="userpass">
            <input style="display:block; margin: 0px;  width: 30%; height: 50px; padding: 0px;" type="submit" value="Show Content">
            </form>
            <script>
            function putCookie(form) {
                var today = new Date();
                var expiry = new Date(today.getTime() + 24 * 3600 * 1000); // plus 1 day
                document.cookie = "userpass=" + escape(form.userpass.value) + "; path=/; expires=" + expiry.toGMTString();
            }
            </script>';
    }
    return $return;
}

You do not required to specify the cookie expire time. If you omit that part, the cookie will be set as so-called session cookie, which would be valid only until user closes his browser:

function putCookie(form) {
    document.cookie = "userpass=" + escape(form.userpass.value) + "; path=/";
}
3
  • Thank you very much Ivan. So, if I understand this correctly, you have already set the expiration of the cookie to 1 day (24 hours) using JS? If I replace the putCookie function inside the $return argument, that will change the "timeout" of the cookie to be removed when the user closes his or her browsing window? Please let me know if I understood that correctly. And of course, a huge thank you. Commented Jul 5, 2020 at 6:52
  • @SofiaHill Yes, you understand all of this correctly. Not bad for just a CSS designer :) When you check this at production, if it would work, please mark the answer as accepted. Commented Jul 5, 2020 at 6:58
  • I'm a fast learner, but I need to start reading more about the WordPress code structure (hooks and filters and what not). Again, thank you for explaining and for taking the time. Commented Jul 5, 2020 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.