允许作者复制但不允许编辑帖子

时间:2017-01-06 作者:Jules Maestro

我需要你的帮助。

我希望作者能够单击前端上的按钮,复制我页面上已有的帖子,并将复制的副本修改并保存为自己的副本。

然而,我不想让他们编辑或删除这些帖子。

这可能吗?既然复制帖子更多的是编辑?是否有任何插件或代码段可以实现这一点?

谢谢

1 个回复
SO网友:Giant Robot

Duplicating a post is a 3-step process:

  1. Create a new post using data from the source post.
  2. Copy the source post\'s metadata over to the new post.
  3. Copy the source post\'s terms over to the new post.

Since you\'re only reading from the source post, duplicating is not more of editing, as you suggest.

Here is a function can do that for you:

/**
 * Duplicate a post as a new draft, setting the current user as author. 
 * Redirect to the post edit screen when done.
 *
 * @param int|string $id A valid post id.
 */
function giant_duplicate_post($id)
{
    // Check for a valid post id.
    if (! is_numeric($id) || $id <= 0)
    {
        // Return, die() or throw an exception, depending on your own requirements.
        return;
    }

    // Get the source post.
    if (! $source = get_post($id))
    {
        // Return, die() or throw an exception, depending on your own requirements.
        return;
    }

    // Create an array suitable for wp_insert_post().
    // We are using data from the source post, but replacing the original author
    // id with the id of the current user.
    $args = array(
        \'post_author\'           => get_current_user_id(),
        \'post_content\'          => $source->post_content,
        \'post_content_filtered\' => $source->post_content_filtered,
        \'post_title\'            => $source->post_title,
        \'post_excerpt\'          => $source->post_excerpt,
        \'post_status\'           => \'draft\',
        \'post_type\'             => $source->post_type,
        \'comment_status\'        => $source->comment_status,
        \'ping_status\'           => $source->ping_status,
        \'post_password\'         => $source->post_password,
        \'to_ping\'               => $source->to_ping,
        \'pinged\'                => $source->pinged,
        \'post_parent\'           => $source->post_parent,
        \'menu_order\'            => $source->menu_order,
    );

    $new_id = wp_insert_post($args);

    // Bail if post creation did not succeed.
    if (is_wp_error($new_id))
    {
        // Return, die() or throw an exception, depending on your own requirements.
        return;
    }

    // Copy the source post\'s taxonomies over to the newly created duplicate.
    foreach (get_object_taxonomies($source->post_type) as $taxonomy)
    {
        $terms = wp_get_object_terms($id, $taxonomy, array(\'fields\' => \'slugs\'));
        wp_set_object_terms($new_id, $terms, $taxonomy, false);
    }

    // Copy the source post\'s metadata over to the newly created duplicate.
    foreach (get_post_meta($id) as $key => $values)
    {
        foreach ($values as $value)
        {
            add_post_meta($new_id, $key, maybe_unserialize($value));
        }
    }

    // Optional: Redirect to the newly created post\'s edit page.
    wp_redirect(get_edit_post_link($new_id, null));
}

WordPress will happily assign any post you create programmatically to any user you specify.

Triggering the process

You ask that the trigger to the process is shown at the frontend. It could be a simple link or a form. For example, you could add this to single.php:

<form method="post">
    <input type="hidden" name="source_id" value="<?php echo esc_attr($post->ID) ?>">
    <input type="hidden" name="nonce" value="<?php echo wp_create_nonce("giant_duplicate_post_{$post->ID}") ?>">
    <input type="submit" value="Duplicate">
</form>

Submitting the form in the example above, will trigger a POST request which you will need to handle with something like the following:

function giant_handle_duplicate_post_request()
{
    $source_id = isset($_REQUEST[\'source_id\']) ? $_REQUEST[\'source_id\'] : null;
    $nonce = isset($_REQUEST[\'nonce\']) ? $_REQUEST[\'nonce\'] : null;

    // Check that the current user is authorised to duplicate posts 
    // and that the process was explicitly triggered from the front end.
    if (is_user_logged_in()
        && current_user_can(\'edit_posts\')
        && $source_id
        && $nonce
        && wp_verify_nonce($nonce, "giant_duplicate_post_{$source_id}"))
    {
        giant_duplicate_post($source_id);
    }
}

add_action(\'parse_request\', \'giant_handle_duplicate_post_request\');

A word of caution

It cannot be stressed enough that YOU need to make sure that only authenticated users can trigger the duplication process!

In the examples above, we\'re checking that the user is logged in, has the edit_posts capability and a valid nonce has been supplied. Your requirements may be different, so take a minute to think it through and apply the required restrictions and safeguards.

相关推荐

是否可以取消对特定帖子类型的POSTS_PER_PAGE限制?

我想知道我是否可以取消特定帖子类型的posts\\u per\\u页面限制。在存档中。php页面我显示不同的帖子类型,对于特定的“出版物”帖子类型,我想显示所有帖子。我如何在不影响传统“post”类型的情况下实现这一点?