I think a combination of the answers so far along with an admin area field to disable the author archive(s) is the best bet.
A class to wrap everything up (along with some constants and methods that will be clear later):
<?php
class Author_Archive_Disabler
{
// meta key that will store the disabled status
const KEY = '_author_archive_disabled';
// nonce name
const NONCE = 'author_archive_nonce';
private static $ins = null;
public static function instance()
{
is_null(self::$ins) && self::$ins = new self;
return self::$ins;
}
public static function init()
{
add_action('plugins_loaded', array(self::instance(), '_setup'));
}
// helper to see if the archive is disabled.
public static function is_disabled($user_id)
{
return 'on' == get_user_meta($user_id, self::KEY, true);
}
// adds actions and such
public function _setup()
{
//
}
}
To add fields you hook into edit_user_profile
(shows fields on profiles other than your own) and show_user_profile
(shows fields on your own profile).
<?php
class Author_Archive_Disabler
{
// snip snip
// adds actions and such
public function _setup()
{
add_action('edit_user_profile', array($this, 'field'));
add_action('show_user_profile', array($this, 'field'));
}
public function field($user)
{
// only let admins do this.
if(!current_user_can('manage_options'))
return;
echo '<h4>', __('Disable Archive', 'author-archive-disabler'), '</h4>';
wp_nonce_field(self::NONCE . $user->ID, self::NONCE, false);
printf(
'<label for="%1$s"><input type="checkbox" name="%1$s" id="%1$s" value="on" %2$s /> %3$s</label>',
esc_attr(self::KEY),
checked(get_user_meta($user->ID, self::KEY, true), 'on', false),
__('Disable Author Archive', 'author-archive-disabler')
);
}
}
Pretty straight forward: only show the field to administrators, print a header, nonce field and the "disable" checkbox itself.
You hook into edit_user_profile_update
(others' profiles) and personal_options_update
(your own profile) to save things.
<?php
class Author_Archive_Disabler
{
// snip snip
// adds actions and such
public function _setup()
{
add_action('edit_user_profile', array($this, 'field'));
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile_update', array($this, 'save'));
add_action('personal_options_update', array($this, 'save'));
}
// snip snip
public function save($user_id)
{
if(
!isset($_POST[self::NONCE]) ||
!wp_verify_nonce($_POST[self::NONCE], self::NONCE . $user_id)
) return; // nonce is no good, bail
if(!current_user_can('edit_user', $user_id))
return; // current user can't edit this user, bail
update_user_meta($user_id, self::KEY,
!empty($_POST[self::KEY]) ? 'on' : 'off');
}
}
Verify the nonce, make sure current user can actually edit the user, then save stuff. if the box is checked, it will go in as "on".
Now hook into template_redirect
, check for the author page and 404 it if it's disabled.
<?php
class Author_Archive_Disabler
{
// snip snip
// adds actions and such
public function _setup()
{
add_action('edit_user_profile', array($this, 'field'));
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile_update', array($this, 'save'));
add_action('personal_options_update', array($this, 'save'));
add_action('template_redirect', array($this, 'maybe_disable'));
}
// snip snip
public function maybe_disable()
{
global $wp_query;
// not an author archive? bail.
if(!is_author())
return;
if(self::is_disabled(get_queried_object_id()))
{
$wp_query->set_404();
}
}
}
You can also filter the author link so a disabled user never gets linked to.
<?php
class Author_Archive_Disabler
{
// snip snip
// adds actions and such
public function _setup()
{
add_action('edit_user_profile', array($this, 'field'));
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile_update', array($this, 'save'));
add_action('personal_options_update', array($this, 'save'));
add_action('template_redirect', array($this, 'maybe_disable'));
add_filter('author_link', array($this, 'change_link'), 10, 2);
}
// snip snip
public function change_link($link, $author_id)
{
if(self::is_disabled($author_id))
return apply_filters('author_archive_disabler_default_url', home_url(), $author_id);
return $link;
}
}
All of the above as a plugin