Discussion:
glitch with the_content filter and password-protected posts
David F. Carr
2014-01-15 13:47:54 UTC
Permalink
A user of one of my plugins is reporting undesirable behavior when he tries
to password protect a post. Even though the body of the post is not
displayed, custom content added from the filter the_the content is
displayed.

My RSVPMaker plugin adds an RSVP form to posts of a custom post type for
events, where the user has specified that RSVPs should be collected. Where
these conditions are met, the HTML for the form is appended to the default
content. It never occurred to me that I needed to test for protected posts
before doing that.

How do I test whether a post is protected and, if so, whether the user has
supplied the required password?

I tried this code below (derived from something I found in the support
forums), but it's not working for me.

if (!empty($post->post_password)) { // if there's a password
if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) { //
and it doesn't match the cookie
return $content; // return filtered content unchanged
}
}

This aborts the filter function on a protected post, but it does so even
after the password is entered. That is, the body copy is displayed but not
the output of my filter function. I can see that the password cookie is
set, but it evaluates as not matching $post->post_password
--
David F. Carr
Author, Social Collaboration for Dummies
http://www.wiley.com/buy/9781118658543
InformationWeek http://www.informationweek.com/authors/David-Carr

LinkedIn - http://www.linkedin.com/in/davidfcarr
Facebook - http://www.facebook.com/carrcomm
Nikola Nikolov
2014-01-15 13:58:23 UTC
Permalink
If you look at how
the_content()<https://github.com/WordPress/WordPress/blob/master/wp-includes/post-template.php#L164>and
get_the_content()<https://github.com/WordPress/WordPress/blob/master/wp-includes/post-template.php#L180>functions
work, you would see that the_content() calls get_the_content()
and then does apply_filters( 'the_content', $content ) to what was
returned.
Inside of get_the_content() though you would see

if ( post_password_required( $post ) )
return get_the_password_form( $post );

( no brackets :ugh: :) )

So it seems like what you should do in your function that adds extra output
is something like this:

if ( post_password_required( $post ) ) {
return '';
}

By returning an empty string when a post password is required(if the user
already entered the password, post_password_required() will return false)
you make sure that none of your output is displayed.
Post by David F. Carr
A user of one of my plugins is reporting undesirable behavior when he tries
to password protect a post. Even though the body of the post is not
displayed, custom content added from the filter the_the content is
displayed.
My RSVPMaker plugin adds an RSVP form to posts of a custom post type for
events, where the user has specified that RSVPs should be collected. Where
these conditions are met, the HTML for the form is appended to the default
content. It never occurred to me that I needed to test for protected posts
before doing that.
How do I test whether a post is protected and, if so, whether the user has
supplied the required password?
I tried this code below (derived from something I found in the support
forums), but it's not working for me.
if (!empty($post->post_password)) { // if there's a password
if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) { //
and it doesn't match the cookie
return $content; // return filtered content unchanged
}
}
This aborts the filter function on a protected post, but it does so even
after the password is entered. That is, the body copy is displayed but not
the output of my filter function. I can see that the password cookie is
set, but it evaluates as not matching $post->post_password
--
David F. Carr
Author, Social Collaboration for Dummies
http://www.wiley.com/buy/9781118658543
InformationWeek http://www.informationweek.com/authors/David-Carr
LinkedIn - http://www.linkedin.com/in/davidfcarr
Facebook - http://www.facebook.com/carrcomm
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
Otto
2014-01-15 14:43:39 UTC
Permalink
Post by Nikola Nikolov
So it seems like what you should do in your function that adds extra output
if ( post_password_required( $post ) ) {
return '';
}
Actually, you want to return the content unchanged, so that the
password form is properly displayed. Filters that do nothing need to
return whatever input they were given, not an empty string.

So, something like this:

add_filter('the_content','example');
function example( $content ) {
$post = get_post();
if ( post_password_required( $post ) ) {
return $content;
}

// .. rest of your filter code here
}


-Otto
Nikola Nikolov
2014-01-15 15:00:05 UTC
Permalink
That's true I forgot that there for a second.
Post by David F. Carr
Post by Nikola Nikolov
So it seems like what you should do in your function that adds extra
output
Post by Nikola Nikolov
if ( post_password_required( $post ) ) {
return '';
}
Actually, you want to return the content unchanged, so that the
password form is properly displayed. Filters that do nothing need to
return whatever input they were given, not an empty string.
add_filter('the_content','example');
function example( $content ) {
$post = get_post();
if ( post_password_required( $post ) ) {
return $content;
}
// .. rest of your filter code here
}
-Otto
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
David F. Carr
2014-01-19 00:57:35 UTC
Permalink
Thanks for your help.

Otto, why do you use $post = get_post() in your example code?

I usually put global $post at the top of the function definition.
Post by Nikola Nikolov
That's true I forgot that there for a second.
Post by David F. Carr
Post by Nikola Nikolov
So it seems like what you should do in your function that adds extra
output
Post by Nikola Nikolov
if ( post_password_required( $post ) ) {
return '';
}
Actually, you want to return the content unchanged, so that the
password form is properly displayed. Filters that do nothing need to
return whatever input they were given, not an empty string.
add_filter('the_content','example');
function example( $content ) {
$post = get_post();
if ( post_password_required( $post ) ) {
return $content;
}
// .. rest of your filter code here
}
-Otto
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
--
David F. Carr
Author, Social Collaboration for Dummies
http://www.wiley.com/buy/9781118658543
InformationWeek http://www.informationweek.com/authors/David-Carr

***@carrcommunications.com

Direct: (954) 757-5827
Mobile: (954) 290-6788
LinkedIn - http://www.linkedin.com/in/davidfcarr
Facebook - http://www.facebook.com/carrcomm

David F. Carr
971 NW 124 Ave.
Coral Springs FL 33071-5082
Otto
2014-01-19 01:15:56 UTC
Permalink
On Sat, Jan 18, 2014 at 6:57 PM, David F. Carr
Post by David F. Carr
Thanks for your help.
Otto, why do you use $post = get_post() in your example code?
I usually put global $post at the top of the function definition.
No particular reason, other than avoiding direct use of globals when
you don't actually need them is always a pretty good idea.

Using a global means that you might modify the global accidentally,
and in this case, I had no need to modify the $post global. On the
other hand, get_post() returns the same global post object anyway, but
now the $post variable is in the function context space, so if I did
accidentally modify it, then the result of that change would not
affect anything else.

-Otto

Loading...