4.4.9. Der komplette Code

Datei drafts-for-friends.php:

<?php
/*
  Plugin Name: Drafts for Friends
  Plugin URI: https://wp-plugin-erstellen.de
  Version: 0.1.0
  Author: Florian Simeth
  Author URI: https://florian-simeth.de
  Description: Allows to create links to draft posts.
  Text Domain: drafts-for-friends
  Domain Path: /languages
  License: GPL
 */

/**
 * Drafts for Friends Plugin.
 *
 * Allows to create links to draft posts.
 *
 * @since      0.1.0
 *
 * @package    WordPress
 * @subpackage drafts-for-friends
 */


add_action( 'admin_menu', 'dff_menus' );

/**
 * Adds the "Draft for Friends" submenu item.
 *
 * This functions adds the submenu item called "Drafts for friends" in posts.
 * It also adds a hook that allows to add new drafts to the list.
 *
 * @since 0.1.0
 *
 * @return void
 */
function dff_menus() {
	$hook = add_submenu_page(
		'edit.php',                                         # parent menu
		__( 'Drafts for Friends', 'drafts-for-friends' ),   # page title
		__( 'Drafts for Friends', 'drafts-for-friends' ),   # menu title
		'manage_options',                                   # capability
		'drafts-for-friends',                               # menu slug
		'dff_settings_page_render'                          # callable function
	);

	// hook into the page so that we can check for POST calls.
	add_action( 'load-' . $hook, 'dff_new_draft_create' );
}


/**
 * Render the settings page.
 *
 * This function renders the settings page of the plugin. It shows a list
 * of released draft posts and a form that allows one to add drafts.
 *
 * @since 0.1.0
 *
 * @return void Outputs HTML code.
 */
function dff_settings_page_render() {
	?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>

		<?php
		/**
		 * Show the list of released posts.
		 */
		include( plugin_dir_path( __FILE__ ) . '/templates/released-posts.php' );

		/**
		 * Show the form to add new draft posts.
		 */
		include( plugin_dir_path( __FILE__ ) . '/templates/new-draft-form.php' );
		?>

    </div>
	<?php
}


/**
 * Output option-Elements for a HTML-select-field.
 *
 * This function outputs HTML option fields to use in a select box. The list includes
 * all draft posts that have not yet been released.
 *
 * @since 0.1.0
 *
 * @return void Outputs HTML code.
 */
function dff_draft_select_options() {
	$query = new WP_Query( array(
		'post_type'   => 'post',
		'post_status' => 'draft',
		'meta_query'  => array(
			array(
				'key'     => 'dff_key',
				'compare' => 'NOT EXISTS',
			),
		),
	) );

	if ( $query->have_posts() ) {
		while ( $query->have_posts() ) {
			$query->the_post();
			printf(
				'<option value="%d">%s</option>',
				get_the_ID(),
				esc_attr( get_the_title() )
			);
		}
	} else {
		printf(
			'<option value="0">%s</option>',
			esc_attr__( 'No drafts found.', 'drafts-for-friends' )
		);
	}
}

/**
 * Adds a new entry to the release post list.
 *
 * This function process the form data that allows one to add a draft post to the release list.
 *
 * @since 0.1.0
 *
 * @return void
 */
function dff_new_draft_create() {

	// Stop if this page has no action.
	if ( ! isset( $_POST['action'] ) ) {
		return;
	}

	// check for the referer and the nonces.
	// check_admin_referer() will die() if the data is not correct.
	$nonce_check = check_admin_referer( 'dff_new_draft' );

	if ( ! $nonce_check ) {
		add_action( 'admin_notices', function () {
			?>
            <div class="notice notice-error is-dismissible">
                <p><?php _e( 'Sorry, you cannot create a new draft.', 'drafts-for-friends' ); ?></p>
            </div>
			<?php
		} );

		return;
	}

	// Get the actual post ID from the _POST array.
	$post_id = absint( $_POST['post_id'] ?? 0 ); // works in PHP > 7.0 only

	// Stop executing if there is not post ID.
	if ( empty( $post_id ) ) {
		add_action( 'admin_notices', function () {
			?>
            <div class="notice notice-error is-dismissible">
                <p><?php _e( 'Please select a valid draft post from the select box.', 'drafts-for-friends' ); ?></p>
            </div>
			<?php
		} );

		return;
	}

	// Add new post meta data and check if it returns TRUE.
	$is_saved = add_post_meta( $post_id, 'dff_key', uniqid() );

	// Show a notice if something went wrong.
	if ( ! $is_saved ) {
		add_action( 'admin_notices', function () {
			?>
            <div class="notice notice-error is-dismissible">
                <p><?php _e( 'Sorry, draft could not be released.', 'drafts-for-friends' ); ?></p>
            </div>
			<?php
		} );

		return;
	}

	// All done. Show success notice to the user.
	add_action( 'admin_notices', function () {
		?>
        <div class="notice notice-success is-dismissible">
            <p><?php _e( 'Draft has been released.', 'drafts-for-friends' ); ?></p>
        </div>
		<?php
	} );

}


add_filter( 'query_vars', 'dff_add_query_var' );

/**
 * Add 'dff_key' variable to query vars.
 *
 * This function adds 'dff_key' to the list of allowed query vars so that we can
 * use it later.
 *
 * @since 0.1.0
 *
 * @param array $vars The list of query vars.
 *
 * @return array The new list of query vars.
 */
function dff_add_query_var( $vars ) {

	$vars[] = 'dff_key';

	return $vars;
}


add_action( 'pre_get_posts', 'dff_intersect' );

/**
 * Checks if a non-logged-in user can see the post and hooks into the database query.
 *
 * This function checks if a non-logged-in user can see the post when the 'dff_key'
 * parameter has been added via the URL. For this we hook into the database query
 * by adding 'draft' to the post_status value and by adding a meta query.
 *
 * @since 0.1.0
 *
 * @param WP_Query $wp_query The current database query object.
 *
 * @return void
 */
function dff_intersect( $wp_query ) {

	// If this is not the main query, stop here.
	if ( ! $wp_query->is_main_query() ) {
		return;
	}

	// We only need to hook into this on post pages.
	if ( ! $wp_query->is_single ) {
		return;
	}

	$key = get_query_var( 'dff_key' );

	// Stop here if there is no key provided.
	if ( empty( $key ) ) {
		return;
	}

	// Get all post_status values (maybe other plugins hook into that, too).
	$post_stati = (array) get_query_var( 'post_status' );

	// Add post_status 'draft'.
	$post_stati[] = 'draft';

	// Remove empty values.
	$post_stati = array_filter( $post_stati );

	// Set the new post_status value.
	set_query_var( 'post_status', $post_stati );

	// Read the meta query (if there are any).
	$meta_queries = (array) get_query_var( 'meta_query' );

	// Add a new meta query.
	$meta_queries[] = array(
		'key'     => 'dff_key',
		'value'   => esc_sql( $key ),
		'compare' => '=',
	);

	// Filter empty meta queries.
	$meta_queries = array_filter( $meta_queries );

	// Set the new meta_query array.
	set_query_var( 'meta_query', $meta_queries );
}


add_action( 'publish_post', 'dff_delete_key_on_transition' );

/**
 * Deletes the 'dff_key' meta key on post transition.
 *
 * This function deletes the 'dff_key' meta value from the database if the
 * user switches the post status to 'publish'.
 *
 * @since 0.1.0
 *
 * @param int $post_id The post ID from the post that was transitioned.
 *
 * @return void
 */
function dff_delete_key_on_transition( $post_id ) {
	delete_post_meta( $post_id, 'dff_key' );
}


add_filter( 'wp_redirect', 'dff_redirect_remove_key' );

/**
 * Remove 'dff_key' paramter on redirects.
 *
 * This function removes the 'dff_key' parameter if WordPress performs a canonical redirect.
 * This usually happens when the URL changes (or if an author publishes a post).
 *
 * @since 0.1.0
 *
 * @param string $url The URL WordPress wants to redirect to.
 *
 * @return string The new redirect URL.
 */
function dff_redirect_remove_key( $url ) {
	$key = get_query_var( 'dff_key' );

	// Stop here if there is no key provided.
	if ( empty( $key ) ) {
		return $url;
	}

	// Check for a post ID.
	$post_id = get_query_var( 'p' );

	// Remove the query argument ('dff_key') if it's there.
	if ( 'draft' != get_post_status( $post_id ) ) {
		$url = remove_query_arg( 'dff_key', $url );
	}

	return $url;
}

Datei templates/new-draft-form.php:

You’re not allowed to see this content. Please log in first.