When a POST is set to private, non-logged in users will receive a 404 message. If you dump the global variable $wp_query
,
var_dump($wp_query);
..you will notice that no post_status
is present in the parameters returned therefore using the slug (or name
parameter of query_vars
array for example) we can get the post status of the POST that is trying to be accessed like so,
global $wp_query;
$slug = $wp_query->query_vars['name'];
$status = get_page_by_path($slug, OBJECT, 'post');
if ($status->post_status == "private") {
//show form
} else {
//etc...
}
Helpful Codex resources:
http://codex.wordpress.org/Function_Reference/get_page_by_path
Update:
On the basis that you are trying to perform this action for the “PAGE” post type (as per your comments) the above code should change 'post'
to 'page'
accordingly in get_page_by_path()
.
Now the reason why it still was not working while using $wp_query->query_vars['name'];
is then related to the fact that your page is a CHILD page of another page, in otherwords it has a PARENT.
Because the function we are using is getting our page by its path, it needs to know its full path so the parent page matters. Therefore we must change,
$slug = $wp_query->query_vars['name'];
to
$slug = $wp_query->query['pagename']; //which will show the full path e.g. parent/child
Elaborating further what we are doing is accessing the full path from a different array within the $wp_query
and here’s an example (sample snippet) of what is $wp_query
is actually comprised of when dumping the results
["query"]=> //we are now accessing the ["query"] array instead of ["query_vars"]
array(2) {
["page"]=>
string(0) ""
["pagename"]=> //and this is what need, notice the full path
string(20) "sample-page/sub-page"
}
["query_vars"]=>
array(57) {
["page"]=>
int(0)
["pagename"]=> //this is what we don't need, no full path contained, will not work
string(8) "sub-page"
etc.......
Therefore the modified code in full will look like;
global $wp_query;
$slug = $wp_query->query['pagename']; //from ->query_vars to ->query
$status = get_page_by_path($slug, OBJECT, 'page'); //change to meet your desired post_type
if ($status->post_status == "private") {
//show form
} else {
//etc...
}
As Kaiser mentioned you can also use, get_post_status()
function to retrieve the post status and that can be done like so,
if (get_post_status($status->ID) == "private") ... etc