Products
GG网络技术分享 2025-03-18 16:12 1
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
Demand feedback