summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/public-post-preview/js/public-post-preview.js6
-rw-r--r--plugins/public-post-preview/js/public-post-preview.min.js2
-rw-r--r--plugins/public-post-preview/public-post-preview.php273
-rw-r--r--plugins/public-post-preview/readme.txt16
4 files changed, 184 insertions, 113 deletions
diff --git a/plugins/public-post-preview/js/public-post-preview.js b/plugins/public-post-preview/js/public-post-preview.js
index 8b7d55f3..cc5d1e12 100644
--- a/plugins/public-post-preview/js/public-post-preview.js
+++ b/plugins/public-post-preview/js/public-post-preview.js
@@ -19,6 +19,10 @@
t.checkbox.bind( 'change', function() {
t.change();
} );
+
+ t.link.find( 'input' ).on( 'focus', function() {
+ $( this ).select();
+ } );
},
/**
@@ -66,7 +70,7 @@
* @since 2.0.0
*
* @param {Object} data The data to send.
- * @param {Object} callback Callback function for a successfull request.
+ * @param {Object} callback Callback function for a successful request.
*/
request : function( data, callback ) {
$.ajax( {
diff --git a/plugins/public-post-preview/js/public-post-preview.min.js b/plugins/public-post-preview/js/public-post-preview.min.js
index b9462266..09df216a 100644
--- a/plugins/public-post-preview/js/public-post-preview.min.js
+++ b/plugins/public-post-preview/js/public-post-preview.min.js
@@ -1 +1 @@
-(function(a){DSPublicPostPreview={initialize:function(){var b=this;b.checkbox=a("#public-post-preview");b.link=a("#public-post-preview-link");b.nonce=a("#public_post_preview_wpnonce");b.status=a("#public-post-preview-ajax");b.status.css("opacity",0);b.checkbox.bind("change",function(){b.change();});},change:function(){var b=this,c=b.checkbox.prop("checked")?1:0;b.link.toggle();b.checkbox.prop("disabled","disabled");b.request({_ajax_nonce:b.nonce.val(),checked:c,post_ID:a("#post_ID").val()},function(d){if(d){if(c){b.status.text(DSPublicPostPreviewL10n.enabled);b._pulsate(b.status,"green");}else{b.status.text(DSPublicPostPreviewL10n.disabled);b._pulsate(b.status,"red");}}b.checkbox.prop("disabled","");});},request:function(b,c){a.ajax({type:"POST",url:ajaxurl,data:a.extend(b,{action:"public-post-preview"}),success:c});},_pulsate:function(c,b){c.css("color",b).animate({opacity:1},600,"linear").animate({opacity:0},600,"linear",function(){c.empty();});}};a(DSPublicPostPreview.initialize());})(jQuery); \ No newline at end of file
+(function(a){DSPublicPostPreview={initialize:function(){var b=this;b.checkbox=a("#public-post-preview");b.link=a("#public-post-preview-link");b.nonce=a("#public_post_preview_wpnonce");b.status=a("#public-post-preview-ajax");b.status.css("opacity",0);b.checkbox.bind("change",function(){b.change();});b.link.find("input").on("focus",function(){a(this).select();});},change:function(){var b=this,c=b.checkbox.prop("checked")?1:0;b.link.toggle();b.checkbox.prop("disabled","disabled");b.request({_ajax_nonce:b.nonce.val(),checked:c,post_ID:a("#post_ID").val()},function(d){if(d){if(c){b.status.text(DSPublicPostPreviewL10n.enabled);b._pulsate(b.status,"green");}else{b.status.text(DSPublicPostPreviewL10n.disabled);b._pulsate(b.status,"red");}}b.checkbox.prop("disabled","");});},request:function(b,c){a.ajax({type:"POST",url:ajaxurl,data:a.extend(b,{action:"public-post-preview"}),success:c});},_pulsate:function(c,b){c.css("color",b).animate({opacity:1},600,"linear").animate({opacity:0},600,"linear",function(){c.empty();});}};a(DSPublicPostPreview.initialize());})(jQuery); \ No newline at end of file
diff --git a/plugins/public-post-preview/public-post-preview.php b/plugins/public-post-preview/public-post-preview.php
index a4f3d717..56bd2dd3 100644
--- a/plugins/public-post-preview/public-post-preview.php
+++ b/plugins/public-post-preview/public-post-preview.php
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: Public Post Preview
- * Version: 2.4.1
+ * Version: 2.5.0
* Description: Enables you to give a link to anonymous users for public preview of any post type before it is published.
* Author: Dominik Schilling
* Author URI: http://wphelper.de/
@@ -13,7 +13,7 @@
*
* Previously (2009-2011) maintained by Jonathan Dingman and Matt Martz.
*
- * Copyright (C) 2012-2014 Dominik Schilling
+ * Copyright (C) 2012-2016 Dominik Schilling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -40,50 +40,30 @@ if ( ! class_exists( 'WP' ) ) {
/**
* The class which controls the plugin.
*
- * Used hooks:
- * - pre_get_posts
- * - query_vars
- * - init
- * - post_submitbox_misc_actions
- * - save_post
- * - posts_results
- * - wp_ajax_public-post-preview
- * - admin_enqueue_scripts
- * - comments_open
- * - pings_open
- *
* Inits at 'plugins_loaded' hook.
- *
*/
class DS_Public_Post_Preview {
/**
- * Hooks into 'pre_get_posts' to handle public preview, only nn-admin
- * Hooks into 'add_meta_boxes' to register the meta box.
- * Hooks into 'save_post' to handle the values of the meta box.
- * Hooks into 'admin_enqueue_scripts' to register JavaScript.
+ * Registers actions and filters.
*
* @since 1.0.0
*/
public static function init() {
add_action( 'init', array( __CLASS__, 'load_textdomain' ) );
+ add_action( 'transition_post_status', array( __CLASS__, 'unregister_public_preview_on_status_change' ), 20, 3 );
+ add_action( 'post_updated', array( __CLASS__, 'unregister_public_preview_on_edit' ), 20, 2 );
if ( ! is_admin() ) {
add_filter( 'pre_get_posts', array( __CLASS__, 'show_public_preview' ) );
-
add_filter( 'query_vars', array( __CLASS__, 'add_query_var' ) );
-
// Add the query var to WordPress SEO by Yoast whitelist.
add_filter( 'wpseo_whitelist_permalink_vars', array( __CLASS__, 'add_query_var' ) );
} else {
add_action( 'post_submitbox_misc_actions', array( __CLASS__, 'post_submitbox_misc_actions' ) );
-
add_action( 'save_post', array( __CLASS__, 'register_public_preview' ), 20, 2 );
-
add_action( 'wp_ajax_public-post-preview', array( __CLASS__, 'ajax_register_public_preview' ) );
-
add_action( 'admin_enqueue_scripts' , array( __CLASS__, 'enqueue_script' ) );
-
add_filter( 'display_post_states', array( __CLASS__, 'display_preview_state' ), 20, 2 );
}
}
@@ -101,6 +81,8 @@ class DS_Public_Post_Preview {
* Registers the JavaScript file for post(-new).php.
*
* @since 2.0.0
+ *
+ * @param string $hook_suffix Unique page identifier.
*/
public static function enqueue_script( $hook_suffix ) {
if ( ! in_array( $hook_suffix, array( 'post.php', 'post-new.php' ) ) ) {
@@ -113,7 +95,7 @@ class DS_Public_Post_Preview {
'public-post-preview',
plugins_url( "js/public-post-preview$suffix.js", __FILE__ ),
array( 'jquery' ),
- self::get_plugin_info( 'Version' ),
+ '20160403',
true
);
@@ -122,7 +104,7 @@ class DS_Public_Post_Preview {
'DSPublicPostPreviewL10n',
array(
'enabled' => __( 'Enabled!', 'public-post-preview' ),
- 'disabled' => __( 'Disabled!', 'public-post-preview' )
+ 'disabled' => __( 'Disabled!', 'public-post-preview' ),
)
);
}
@@ -131,6 +113,10 @@ class DS_Public_Post_Preview {
* Adds "Public Preview" to the list of display states used in the Posts list table.
*
* @since 2.4.0
+ *
+ * @param array $post_states An array of post display states.
+ * @param WP_Post $post The current post object.
+ * @return Filtered array of post display states.
*/
public static function display_preview_state( $post_states, $post ) {
if ( in_array( $post->ID, self::get_preview_post_ids() ) ) {
@@ -148,7 +134,7 @@ class DS_Public_Post_Preview {
public static function post_submitbox_misc_actions() {
$post_types = get_post_types(
array(
- 'public' => true
+ 'public' => true,
)
);
@@ -158,12 +144,12 @@ class DS_Public_Post_Preview {
return false;
}
- // Do nothing for auto drafts
- if ( $post->post_status == 'auto-draft' ) {
+ // Do nothing for auto drafts.
+ if ( 'auto-draft' === $post->post_status ) {
return false;
}
- // Post is already published
+ // Post is already published.
if ( in_array( $post->post_status, self::get_published_statuses() ) ) {
return false;
}
@@ -179,7 +165,7 @@ class DS_Public_Post_Preview {
/**
* Returns post statuses which represent a published post.
*
- * @since 2.4.0
+ * @since 2.4.0
*
* @return array List with post statuses.
*/
@@ -192,9 +178,9 @@ class DS_Public_Post_Preview {
/**
* Prints the checkbox with the input field for the preview link.
*
- * @since 2.0.0
+ * @since 2.0.0
*
- * @param WP_Post $post The post object.
+ * @param WP_Post $post The post object.
*/
private static function get_checkbox_html( $post ) {
if ( empty( $post ) ) {
@@ -204,12 +190,12 @@ class DS_Public_Post_Preview {
wp_nonce_field( 'public_post_preview', 'public_post_preview_wpnonce' );
$preview_post_ids = self::get_preview_post_ids();
- $enabeld = in_array( $post->ID, $preview_post_ids );
+ $enabled = in_array( $post->ID, $preview_post_ids );
?>
- <label><input type="checkbox"<?php checked( $enabeld ); ?> name="public_post_preview" id="public-post-preview" value="1" />
+ <label><input type="checkbox"<?php checked( $enabled ); ?> name="public_post_preview" id="public-post-preview" value="1" />
<?php _e( 'Enable public preview', 'public-post-preview' ); ?> <span id="public-post-preview-ajax"></span></label>
- <div id="public-post-preview-link" style="margin-top:6px"<?php echo $enabeld ? '' : ' class="hidden"'; ?>>
+ <div id="public-post-preview-link" style="margin-top:6px"<?php echo $enabled ? '' : ' class="hidden"'; ?>>
<label>
<input type="text" name="public_post_preview_link" class="regular-text" value="<?php echo esc_attr( self::get_preview_link( $post ) ); ?>" style="width:99%" readonly />
<span class="description"><?php _e( '(Copy and share this link.)', 'public-post-preview' ); ?></span>
@@ -219,18 +205,18 @@ class DS_Public_Post_Preview {
}
/**
- * Returns the public preview link.
- *
- * The link is the home link with these parameters:
- * - preview, always true (query var for core)
- * - _ppp, a custom nonce, see DS_Public_Post_Preview::create_nonce()
- * - page_id or p or p and post_type to specify the post.
- *
- * @since 2.0.0
- *
- * @param WP_Post $post The post object.
- * @return string The generated public preview link.
- */
+ * Returns the public preview link.
+ *
+ * The link is the home link with these parameters:
+ * - preview, always true (query var for core)
+ * - _ppp, a custom nonce, see DS_Public_Post_Preview::create_nonce()
+ * - page_id or p or p and post_type to specify the post.
+ *
+ * @since 2.0.0
+ *
+ * @param WP_Post $post The post object.
+ * @return string The generated public preview link.
+ */
private static function get_preview_link( $post ) {
if ( 'page' == $post->post_type ) {
$args = array(
@@ -260,11 +246,11 @@ class DS_Public_Post_Preview {
*
* Don't runs on an autosave and ignores post revisions.
*
- * @since 2.0.0
+ * @since 2.0.0
*
- * @param int $post_id The post id.
- * @param object $post The post object.
- * @return bool Returns false on a failure, true on a success.
+ * @param int $post_id The post id.
+ * @param object $post The post object.
+ * @return bool Returns false on a failure, true on a success.
*/
public static function register_public_preview( $post_id, $post ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
@@ -285,12 +271,11 @@ class DS_Public_Post_Preview {
if ( empty( $_POST['public_post_preview'] ) && in_array( $preview_post_id, $preview_post_ids ) ) {
$preview_post_ids = array_diff( $preview_post_ids, (array) $preview_post_id );
} elseif (
- ! empty( $_POST['public_post_preview'] ) &&
- ! empty( $_POST['original_post_status'] ) &&
- 'publish' != $_POST['original_post_status'] &&
- 'publish' == $post->post_status &&
- in_array( $preview_post_id, $preview_post_ids )
- ) {
+ ! empty( $_POST['public_post_preview'] ) &&
+ ! empty( $_POST['original_post_status'] ) &&
+ ! in_array( $_POST['original_post_status'], self::get_published_statuses() ) &&
+ in_array( $post->post_status, self::get_published_statuses() )
+ ) {
$preview_post_ids = array_diff( $preview_post_ids, (array) $preview_post_id );
} elseif ( ! empty( $_POST['public_post_preview'] ) && ! in_array( $preview_post_id, $preview_post_ids ) ) {
$preview_post_ids = array_merge( $preview_post_ids, (array) $preview_post_id );
@@ -302,11 +287,73 @@ class DS_Public_Post_Preview {
}
/**
+ * Unregisters a post for public preview when a (scheduled) post gets published
+ * or trashed.
+ *
+ * @since 2.5.0
+ *
+ * @param string $new_status New post status.
+ * @param string $old_status Old post status.
+ * @param WP_Post $post Post object.
+ * @return bool Returns false on a failure, true on a success.
+ */
+ public static function unregister_public_preview_on_status_change( $new_status, $old_status, $post ) {
+ $disallowed_status = self::get_published_statuses();
+ $disallowed_status[] = 'trash';
+
+ if ( in_array( $new_status, $disallowed_status ) ) {
+ return self::unregister_public_preview( $post->ID );
+ }
+
+ return false;
+ }
+
+ /**
+ * Unregisters a post for public preview when a post gets published or trashed.
+ *
+ * @since 2.5.0
+ *
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
+ * @return bool Returns false on a failure, true on a success.
+ */
+ public static function unregister_public_preview_on_edit( $post_id, $post ) {
+ $disallowed_status = self::get_published_statuses();
+ $disallowed_status[] = 'trash';
+
+ if ( in_array( $post->post_status, $disallowed_status ) ) {
+ return self::unregister_public_preview( $post_id );
+ }
+
+ return false;
+ }
+
+ /**
+ * Unregisters a post for public preview.
+ *
+ * @since 2.5.0
+ *
+ * @param int $post_id Post ID.
+ * @return bool Returns false on a failure, true on a success.
+ */
+ private static function unregister_public_preview( $post_id ) {
+ $preview_post_ids = self::get_preview_post_ids();
+
+ if ( ! in_array( $post_id, $preview_post_ids ) ) {
+ return false;
+ }
+
+ $preview_post_ids = array_diff( $preview_post_ids, (array) $post_id );
+
+ return self::set_preview_post_ids( $preview_post_ids );
+ }
+
+ /**
* (Un)Registers a post for a public preview for an AJAX request.
*
- * @since 2.0.0
+ * Returns '0' on a failure, '1' on success.
*
- * @return string Returns '0' on a failure, '1' on success.
+ * @since 2.0.0
*/
public static function ajax_register_public_preview() {
check_ajax_referer( 'public_post_preview' );
@@ -344,8 +391,9 @@ class DS_Public_Post_Preview {
/**
* Registers the new query var `_ppp`.
*
- * @since 2.1.0
+ * @since 2.1.0
*
+ * @param array $qv Existing list of query variables.
* @return array List of query variables.
*/
public static function add_query_var( $qv ) {
@@ -360,10 +408,10 @@ class DS_Public_Post_Preview {
* Filter will be set if it's the main query, a preview, a singular page
* and the query var `_ppp` exists.
*
- * @since 2.0.0
+ * @since 2.0.0
*
- * @param object $query The WP_Query object.
- * @return object The WP_Query object, unchanged.
+ * @param object $query The WP_Query object.
+ * @return object The WP_Query object, unchanged.
*/
public static function show_public_preview( $query ) {
if (
@@ -382,10 +430,10 @@ class DS_Public_Post_Preview {
* Checks if a public preview is available and allowed.
* Verifies the nonce and if the post id is registered for a public preview.
*
- * @since 2.0.0
+ * @since 2.0.0
*
- * @param int $post_id The post id.
- * @return bool True if a public preview is allowed, false on a failure.
+ * @param int $post_id The post id.
+ * @return bool True if a public preview is allowed, false on a failure.
*/
private static function is_public_preview_available( $post_id ) {
if ( empty( $post_id ) ) {
@@ -404,16 +452,39 @@ class DS_Public_Post_Preview {
}
/**
+ * Filters the HTML output of individual page number links to use the
+ * preview link.
+ *
+ * @since 2.5.0
+ *
+ * @param string $link The page number HTML output.
+ * @param int $page_number Page number for paginated posts' page links.
+ * @return string The filtered HTML output.
+ */
+ public static function filter_wp_link_pages_link( $link, $page_number ) {
+ $post = get_post();
+ if ( ! $post ) {
+ return $link;
+ }
+
+ $preview_link = self::get_preview_link( $post );
+ $preview_link = add_query_arg( 'page', $page_number, $preview_link );
+
+ return preg_replace( '~href=(["|\'])(.+?)\1~', 'href=$1' . $preview_link . '$1', $link );
+ }
+
+ /**
* Sets the post status of the first post to publish, so we don't have to do anything
* *too* hacky to get it to load the preview.
*
* @since 2.0.0
*
- * @param array $posts The post to preview.
+ * @param array $posts The post to preview.
+ * @return array The post that is being previewed.
*/
public static function set_post_to_publish( $posts ) {
// Remove the filter again, otherwise it will be applied to other queries too.
- remove_filter( 'posts_results', array( __CLASS__, 'set_post_to_publish' ), 10, 2 );
+ remove_filter( 'posts_results', array( __CLASS__, 'set_post_to_publish' ), 10 );
if ( empty( $posts ) ) {
return;
@@ -421,16 +492,17 @@ class DS_Public_Post_Preview {
$post_id = $posts[0]->ID;
- // If the post has gone live, redirect to it's proper permalink
+ // If the post has gone live, redirect to it's proper permalink.
self::maybe_redirect_to_published_post( $post_id );
if ( self::is_public_preview_available( $post_id ) ) {
- // Set post status to publish so that it's visible
+ // Set post status to publish so that it's visible.
$posts[0]->post_status = 'publish';
- // Disable comments and pings for this post
+ // Disable comments and pings for this post.
add_filter( 'comments_open', '__return_false' );
add_filter( 'pings_open', '__return_false' );
+ add_filter( 'wp_link_pages_link', array( __CLASS__, 'filter_wp_link_pages_link' ), 10, 2 );
}
return $posts;
@@ -441,7 +513,8 @@ class DS_Public_Post_Preview {
*
* @since 2.0.0
*
- * @param int $post_id The post id.
+ * @param int $post_id The post id.
+ * @return false False of post status is not a published status.
*/
private static function maybe_redirect_to_published_post( $post_id ) {
if ( ! in_array( get_post_status( $post_id ), self::get_published_statuses() ) ) {
@@ -455,11 +528,11 @@ class DS_Public_Post_Preview {
/**
* Get the time-dependent variable for nonce creation.
*
- * @see wp_nonce_tick()
+ * @see wp_nonce_tick()
*
- * @since 2.1
+ * @since 2.1.0
*
- * @return int The time-dependent variable
+ * @return int The time-dependent variable.
*/
private static function nonce_tick() {
$nonce_life = apply_filters( 'ppp_nonce_life', 60 * 60 * 48 ); // 48 hours
@@ -470,12 +543,12 @@ class DS_Public_Post_Preview {
/**
* Creates a random, one time use token. Without an UID.
*
- * @see wp_create_nonce()
+ * @see wp_create_nonce()
*
- * @since 1.0.0
+ * @since 1.0.0
*
* @param string|int $action Scalar value to add context to the nonce.
- * @return string The one use form token
+ * @return string The one use form token.
*/
private static function create_nonce( $action = -1 ) {
$i = self::nonce_tick();
@@ -486,35 +559,35 @@ class DS_Public_Post_Preview {
/**
* Verifies that correct nonce was used with time limit. Without an UID.
*
- * @see wp_verify_nonce()
+ * @see wp_verify_nonce()
*
- * @since 1.0.0
+ * @since 1.0.0
*
- * @param string $nonce Nonce that was used in the form to verify
- * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
+ * @param string $nonce Nonce that was used in the form to verify.
+ * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
* @return bool Whether the nonce check passed or failed.
*/
private static function verify_nonce( $nonce, $action = -1 ) {
$i = self::nonce_tick();
- // Nonce generated 0-12 hours ago
+ // Nonce generated 0-12 hours ago.
if ( substr( wp_hash( $i . $action, 'nonce' ), -12, 10 ) == $nonce ) {
return 1;
}
- // Nonce generated 12-24 hours ago
+ // Nonce generated 12-24 hours ago.
if ( substr( wp_hash( ( $i - 1 ) . $action, 'nonce' ), -12, 10 ) == $nonce ) {
return 2;
}
- // Invalid nonce
+ // Invalid nonce.
return false;
}
/**
* Returns the post ids which are registered for a public preview.
*
- * @since 2.0.0
+ * @since 2.0.0
*
* @return array The post ids. (Empty array if no ids are registered.)
*/
@@ -525,33 +598,17 @@ class DS_Public_Post_Preview {
/**
* Saves the post ids which are registered for a public preview.
*
- * @since 2.0.0
+ * @since 2.0.0
*
+ * @param array $post_ids List of post IDs that have a preview.
* @return array The post ids. (Empty array if no ids are registered.)
*/
- private static function set_preview_post_ids( $post_ids = array( )) {
+ private static function set_preview_post_ids( $post_ids = array() ) {
return update_option( 'public_post_preview', $post_ids );
}
/**
- * Small helper to get some plugin info.
- *
- * @since 2.0.0
- *
- * @param string $key The key to get the info from, see get_plugin_data().
- * @return string|bool Either the value, or if the key doesn't exists false.
- */
- private static function get_plugin_info( $key = null ) {
- $plugin_data = get_plugin_data( __FILE__);
- if ( array_key_exists( $key, $plugin_data ) ) {
- return $plugin_data[ $key ];
- }
-
- return false;
- }
-
- /**
- * Delets the option 'public_post_preview' if the plugin will be uninstalled.
+ * Deletes the option 'public_post_preview' if the plugin will be uninstalled.
*
* @since 2.0.0
*/
diff --git a/plugins/public-post-preview/readme.txt b/plugins/public-post-preview/readme.txt
index 16a4f7c4..e26e378e 100644
--- a/plugins/public-post-preview/readme.txt
+++ b/plugins/public-post-preview/readme.txt
@@ -3,8 +3,8 @@ Contributors: ocean90
Tags: public, post, preview, posts, custom post types, draft
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VR8YU922B7K46
Requires at least: 3.5
-Tested up to: 4.4
-Stable tag: 2.4.1
+Tested up to: 4.5
+Stable tag: 2.5.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -24,7 +24,7 @@ Have you ever been writing a post with the help of someone who does not have acc
If you want, you can drop me a line @[ocean90](http://twitter.com/ocean90) on Twitter or @[Dominik Schilling](https://plus.google.com/+DominikSchilling/) on Google+.
= More =
-Try also some of my [other plugins](http://profiles.wordpress.org/users/ocean90) or visit my site [wpGrafie.de](http://wpgrafie.de/).
+Try also some of my [other plugins](http://profiles.wordpress.org/users/ocean90).
*Thanks to Hans Dinkelberg for his [photo](http://www.flickr.com/photos/uitdragerij/7516234430/).*
@@ -60,6 +60,11 @@ To upload the plugin through WordPress, instead of FTP:
== Frequently Asked Questions ==
+**I can't find the option for preview links. Where is it?**
+
+The checkbox is only available for non-published posts and once a post was saved as a draft.
+
+
**After some time the preview link returns the message "The link has been expired!". Why?**
The plugin generates an URL with an expiring nonce. By default a link "lives" 48 hours. After 48 hours the link is expired and you need to copy and share a new link which is automatically generated on the same place under the editor.
@@ -77,6 +82,11 @@ function my_nonce_life() {
Or use the [Public Post Preview Configurator](https://wordpress.org/plugins/public-post-preview-configurator/).
== Change Log ==
+= 2.5.0 (2016-04-05): =
+* Auto select preview link on focus. Props [@JeroenSormani](https://github.com/JeroenSormani).
+* Remove preview status from posts which are trashed or after scheduled posts are published.
+* Add support for paged posts.
+
= 2.4.1 (2015-10-13): =
* Update text domain to support language packs. Translations are now managed via http://translate.wordpress.org/projects/wp-plugins/public-post-preview.