Skip to content

Instantly share code, notes, and snippets.

@enishant
Forked from gmazzap/PrivatePostAccess.php
Created March 4, 2014 11:07
Show Gist options
  • Save enishant/9344429 to your computer and use it in GitHub Desktop.
Save enishant/9344429 to your computer and use it in GitHub Desktop.
<?php
/**
* Plugin Name: Private Post Access
* Plugin URI: http://wordpress.stackexchange.com/questions/130967/get-full-page-html-for-a-non-public-wordpress-page
* Description: Generate and handle urls that allow access to posts in non-public status.
* Author: G. M.
* Author URI: http://wordpress.stackexchange.com/users/35541/g-m
*
*/
/**
* HOW TO USE
*
* First of all
* - install this file as a plugin and activate
* - OR just include this file in theme functions.php or in another plugin.
*
* After that, the url to use to show the post even if in private state should be get using:
*
* PrivatePostAccess::url( $post ); instead of get_permalink( $post );
*
* The variable $post can be a post id or a post object.
*
* Sending a request using that url will show the post even if in a not public state, e.g. draft or pending.
* that url can also be used to retrieve a post html using HTTP API or raw cUrl
*
* Example:
*
*
* $url = PrivatePostAccess::url( 605 ); // 605 is the post ID
*
* if ( filter_var( $url, FILTER_VALIDATE_URL ) ) {
* $response = wp_remote_get( $url );
* $post_full_body = $response ? wp_remote_retrieve_body( $response ) : FALSE;
* }
*
*/
class PrivatePostAccess {
// change this string to whatever you want
const SECRET = 'ASlajADFA71scfas57dFsdtfgasd897Vsd';
private static $hooksdone = array();
private $requested_status;
private $requested_was_public = TRUE;
/**
* Get the url of a post that will allow to get post even if it has a not public status
*
* @param mixed $post post id, post object or null (inside the loop)
* @return string post url
* @access public
*/
static function url( $post = NULL ) {
if ( empty($post) ) global $post;
if ( is_numeric($post) ) $post = get_post( $post );
if ( ! $post instanceof WP_Post ) return FALSE;
if ( self::isPublic($post) ) return get_permalink($post);
$nonce = wp_create_nonce( __CLASS__ );
$vars = array('nonce' => $nonce, 'key' => self::SECRET );
return add_query_arg( $vars, get_permalink($post) );
}
/**
* Check if the status of a post is public or not
*
* @param WP_Post $post post object
* @return bool true if post status is public, false otherwise
* @access protected
*/
protected static function isPublic( WP_Post $post = NULL ) {
if ( $post instanceof WP_Post ) {
$status = get_post_status( $post );
$post_status_obj = get_post_status_object( $status );
return $post_status_obj->public;
}
}
/**
* Init the plugin
*
* @return null
* @access public
*/
function init() {
add_action('pre_get_posts', array($this, 'hooks') );
}
/**
* Add the hook needed to allow not public post to be visible
*
* @param WP_Query $query current main query
* @return null
* @access public
*/
function hooks( WP_Query $query ) {
if ( current_filter() !== 'pre_get_posts' || isset( self::$hooksdone[current_filter()] ) ) return;
self::$hooksdone[current_filter()] = 1;
if ( ! is_admin() && $query->is_main_query() && is_singular() ) {
add_filter('posts_results', array($this, 'enable') );
add_filter('the_posts', array($this, 'enable') );
}
}
/**
* Run on two hooks, 'posts_results' and 'the_posts'
* on first fake global $wp_post_statuses to make current post status appear public,
* on second restore the status
*
* @param WP_Post $results the current queried post
* @return WP_Post
* @access public
*/
function enable( $results ) {
if ( isset( self::$hooksdone[current_filter()] ) ) return $results;
self::$hooksdone[current_filter()] = 1;
if ( ! is_admin() && $this->checkRequest() ) {
global $wp_post_statuses;
if ( current_filter() === 'posts_results' && ! $this->isPublic($results[0]) ) {
$this->requested_status = get_post_status( $results[0] );
$this->requested_was_public = FALSE;
$wp_post_statuses[$this->requested_status]->public = TRUE;
} elseif ( ( current_filter() === 'the_posts' ) && ! $this->requested_was_public ) {
$wp_post_statuses[$this->requested_status]->public = FALSE;
}
}
return $results;
}
/**
* Check the request to verify query vars
*
* @return null|bool
* @access protected
*/
protected function checkRequest() {
static $good;
if ( is_null($good) ) {
$good = $this->checkNonce() && $this->checkSecret();
}
return $good;
}
/**
* Check the request to verify nonce
*
* @return bool
* @access protected
*/
protected function checkNonce() {
$nonce = filter_input( INPUT_GET, 'nonce', FILTER_SANITIZE_STRING );
return ( ! empty($nonce) && wp_verify_nonce($nonce, __CLASS__) );
}
/**
* Check the request to verify nonce
*
* @return bool
* @access protected
*/
protected function checkSecret() {
$key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_STRING );
return ( ! empty($key) && $key === self::SECRET );
}
}
add_action( 'init', array( new PrivatePostAccess, 'init' ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment