简体   繁体   中英

How to dynamically assign author to post in WordPress?

I'm creating a WordPress plugin which has a custom meta-box that lists checkboxes of authors and contributors. When checked, the list shows up on frontend at the end of the post. What I need to do is: When user clicks the name of a contributor, it reverts to archives page, but the post isn't listed under the name of that contributors.

How can I update and save a post under multiple contributors so that it is showed under the author's archives page?

This is the custom meta-box callback function and the function which is called when the post is saved:

function cd_meta_box_cb($post)
{
    global $post;
    echo'<b> Select the contributors that have contributed to this post: </b>';
    echo '<br><br>';
    wp_nonce_field('my_meta_box_nonce', 'meta_box_nonce');
    global $wpdb;

    $authors=$wpdb->get_results("SELECT wp_users.ID, wp_users.user_nicename 
    FROM wp_users INNER JOIN wp_usermeta 
    ON wp_users.ID = wp_usermeta.user_id 
    WHERE wp_usermeta.meta_key = 'wp_capabilities' 
    AND wp_usermeta.meta_value LIKE '%author%' OR wp_usermeta.meta_value LIKE '%editor%'  
    ORDER BY wp_users.user_nicename");

    $current_user = wp_get_current_user();
    foreach ($authors as $author) {
        $author_info=get_userdata($author->ID);
        //$author_role=$author_info->roles;
        $author_first_name=$author_info->first_name;
        $author_last_name=$author_info->last_name;
        if(strcmp($current_user->user_nicename,$author->user_nicename)==0)
        {       
            echo"<input type='checkbox' id='my_meta_box_check' name='my_meta_box_check[]'";
            echo"value=";
            the_author_meta('user_nicename', $author->ID);
            echo" checked disabled>";

            echo"<input type='hidden' id='my_meta_box_check' name='my_meta_box_check[]'";
            echo"value=";
            the_author_meta('user_nicename', $author->ID);
            echo">";
        }
        else
        {
            echo"<input type='checkbox' id='my_meta_box_check' name='my_meta_box_check[]'";
            echo"value=";
            the_author_meta('user_nicename', $author->ID);
            echo">";    
        }
        echo $author_first_name ." ". $author_last_name ." ";
        echo"(";
        echo"<label id='labelid' for='author'>";
        the_author_meta('user_nicename', $author->ID);
        echo"</label>";
        echo")";
        echo "<br />";
    }
}
//save custom data when our post is saved
function save_custom_data($post_id)
{
    global $post,$wpdb;

    $contributor=get_post_meta($post->ID, 'my_meta_box_check', true);
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!isset($_POST['meta_box_nonce']) || !wp_verify_nonce($_POST['meta_box_nonce'], 'my_meta_box_nonce')) return;
    if (!current_user_can('edit_post')) return;
    if (isset($_POST['my_meta_box_check'])) 
    {
        update_post_meta($post_id, 'my_meta_box_check', $_POST['my_meta_box_check']);
        $tablename = $wpdb->prefix.'authorlist';
        $wpdb->insert($tablename,array('authorname'=>$post_id,'authorpost'=>$contributor));
    }
    else 
    {
        delete_post_meta($post_id, 'my_meta_box_check');
    }
}

add_action('save_post', 'save_custom_data');

Add this to your theme's 'functions.php' or plugin.

add_action( 'pre_get_posts', 'modify_author_query' );

function modify_author_query( $query ) {
    // check if on front-end and author query is modified
    if ( ! is_admin() && is_main_query() && $query->is_author() ) {
        $author_name =  $query->query_vars['author_name'];
        //$userdata = get_user_by('slug',$author_name);
        //$userid = $user->ID;

        $meta_query = array(  
            array(
                'key' => 'my_meta_box_check',
                'value' => $author_name,
                'compare' => 'LIKE'
            )
        );
        $query->set( 'meta_query', $meta_query );

        // unset the default author since we are using custom meta
        unset( $query->query_vars['author_name'] );
    }
}

Please note that above may show wrong results if part of a user name matches with another - try saving the data as comma separated string (should begin and end with comma) and replace 'value' => $author_name with 'value' => ','.$author_name.',' .

Well, first off Wordpress is intend to have one author in a post. So we need to start from there.

My approach would be just use the Wordpress author field as the main author and have my own field for 'secondary' authors.

This way you can just hook up to author page queries and add, besides posts where the user is the author, posts where the user is saved under your meta.

Not quoting any code since your problem seems to be more of a wrong approach than not-knowing-code.

add_filter('posts_where', function($where){
      if(!is_admin() && is_author() && is_main_query() ){
            $where = "AND ((dev_posts.post_author = ".get_queried_object_id().") OR ( ( dev_postmeta.meta_key = 'auth_id' AND dev_postmeta.meta_value LIKE '%:\"'.get_queried_object_id().'\"\;%' ) )) AND dev_posts.post_type = 'post' AND (dev_posts.post_status = 'publish' OR dev_posts.post_status = 'private')";
    }
    return $where;
});

add_action('pre_get_posts', function($query){
    if(!is_admin() && is_author() && is_main_query() ){
        $query->set('relation', 'or');
        $query->set('meta_query', array(array(
            'key' => 'auth_id',
            'value' => ':'.get_queried_object_id().';',
            'compare' => 'LIKE'
        )));
    }
}); 

"dev" is my db prefix so you need to replace with $wpdb->prefix

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM