I essentially want password protected/private pages/posts in WP to work as they currently do, but completely disregard the functionality for certain IP addresses.
I’ve looked into filters/actions and don’t see anything that seems promising, again I would prefer to do this without creating a specific category or anything outside of the current functionality of this in wordpress.
Thanks!
Bypass Password Protected Posts
You are, unfortunately right about the lack of filters, and hacking the core is inevitable. One solutions that seems to work revolves around the
sanitize_post_field()
function which fires off a number of interesting filters if its$context
argument is not set toraw
.The template function that is responsible for deciding whether to show the password field or the content is http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/post-template.php#L556
Notice how nice it would be to void the
post_password
? Let’s dig in…See how the post is acquired through the
get_post()
function:http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/post.php#L370
The function contains no filters or actions to hook into, but
sanitize_post_field()
contains some filters that can be hooked into, andpost_password
goes through that function.Please refer to the function http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/post.php#L1676
Notice, however, that if
$context == 'raw';
the function returns, and none of the filters are fired off. So a little core hack is required that will make the flow of the code reach those filters.Will force the
$context
to be anything butraw
. This will permit to do something along the following lines:This will effectively remove the password, so the test http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/post-template.php#L556
if ( empty($post->post_password) )
is evaluated totrue
allowing you to bypass the password. There should be no implications by getting the post with adisplay
context, as it is used only for the retrieval of thepost_password
.You can as well create your own filter in the core around the
post_password_required()
function mentioned above, not to overcomplicate things, maybe. Up to you.Bypass Private Posts
Now, as for private posts, refer to this bit or query.php http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/query.php#L2649 as this is where the found post get stripped off of private entries.
And you’d be tempted to hook into the http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/query.php#L2625
posts_results
filter and go in and alter thepost_status
for each post fromprivate
topublic
… however, as you may have seen theget_post_status()
function works on its own copy of a post that it gets fromget_post()
… …which again has no filters butsanitize_post_field()
does, which again requires a$context
of anything butraw
. So again:And hook into a filter to trick the function into thinking that the post is published by doing this:
Or wrap your own filter around the
get_post_status()
function.Conclusion
Once you understand which parts of the core are responsible for blocking the posts you can attempt to modify them however you require, so I hope my long answer helps to an extent, and someone follows up with more tips and perhaps better solutions. Great question, got me digging and thinking.
You don’t need to change core, just add action to
pre_get_posts
and do your check:You can show or hide private posts to specific countries or IPs.