initialize(); $this->admin_initialize(); /* Hooks and filters */ add_action( 'admin_menu', array( &$this, 'create_options_menu' ) ); // Add menu entry to Settings menu add_action( 'admin_init', array( &$this, 'options_init' ) ); // Initialize plugin options add_action( 'add_meta_boxes', array( &$this, 'add_metabox' ) ); // Add metabox to post/page editing screen add_action( 'admin_enqueue_scripts', array( &$this, 'add_metabox_scripts' ) ); // Load scripts and styles add_action( 'save_post', array( &$this, 'save_meta' ) ); // Hook WordPress to save meta box data when saving post/page // AJAX hooks add_action( 'wp_ajax_cc_author_change_postauthor', array( &$this, 'change_postauthor_callback' ) ); // Change the post author in the meta box // Hooks and filters for the editor if ( function_exists( 'wp_editor' ) ) { add_action( 'show_user_profile', array( &$this, 'editorprofile' ) ); // User profile add_action( 'edit_user_profile', array( &$this, 'editorprofile' ) ); // User profile add_action( 'admin_init', array( &$this, 'editor_remove_filters' ) ); // Remove filters from textarea add_action( 'admin_enqueue_scripts', array( &$this, 'profilejs' ) ); // Load JavaScript } // End hooks and filters } // __construct() /* ===== Plugin options ===== */ /** * Create the menu entry under the Settings menu */ function create_options_menu() { add_options_page( self::NAME, // Page title. This is displayed in the browser title bar. self::NAME, // Menu title. This is displayed in the Settings submenu. 'manage_options', // Capability required to access the options page for this plugin self::ID, // Menu slug array( &$this, 'options_page' ) // Function to render the options page ); } // create_options_menu() /** * Initialize plugin options */ function options_init() { // Register the plugin options call and the sanitation callback register_setting( self::PREFIX . 'options_fields', // The namespace for plugin options fields. This must match settings_fields() used when rendering the form. self::PREFIX . 'options', // The name of the plugin options entry in the database. array( &$this, 'options_validate' ) // The callback method to validate plugin options ); // Settings section for Post/Page options add_settings_section( 'postpage', // Name of the section 'Post/Page Settings', // Title of the section, displayed on the options page array( &$this, 'postpage_callback' ), // Callback method to display plugin options self::ID // Page ID for the options page ); // Whether to display per-post author information add_settings_field( 'perpost', // Field ID 'Use author data from post', // Field title/label, displayed to the user array( &$this, 'perpost_callback' ), // Callback method to display the option field self::ID, // Page ID for the options page 'postpage' // Settings section in which to display the field ); // Add rel="nofollow" to links inside an author's biographical info add_settings_field( 'relnofollow', // Field ID 'Add rel="nofollow" to links in author bio', // Field title/label, displayed to the user array( &$this, 'relnofollow_callback' ), // Callback method to display the option field self::ID, // Page ID for the options page 'postpage' // Settings section in which to display the field ); } // options_init() /** * Callback for post/page options section */ function postpage_callback() { echo '

These options are specific to posts and pages.

'; } // postpage_callback() /** * Callback for admin option section */ function admin_options_callback() { echo '

These options are for things that happen inside WordPress admin.

'; } // admin_options_callback() /** * Callback for per-post author information option */ function perpost_callback() { // Check the status of this option in the database if ( isset( $this->options['perpost'] ) ) { $checked = 'checked'; } else { $checked = NULL; } echo ''; // Print the input field to the screen echo '

Display author information from the post metadata instead of the user database. Useful for keeping author information specific to the time a post was published.

Note: You can toggle this at any time, as this plugin always saves author information to post metadata regardless of this setting.

'; // Description of option } // perpost_callback() /** * Callback for rel="nofollow" option */ function relnofollow_callback() { // Check the status of this option in the database if ( isset( $this->options['relnofollow'] ) ) { $checked = 'checked'; } else { $checked = NULL; } echo ''; // Print the input field to the screen echo '

Add a rel="nofollow" attribute to any links in an author\'s biographical info when displayed. This prevents search engines from counting those links as part of your rank score. If you\'re unsure what this is, leave it checked.

'; // Description of option } // relnofollow_callback() // Validate options when submitted function options_validate( $input ) { // Set local variable for plugin options stored in the database $options = $this->options; // Directly set options that require no validation (such as checkboxes) $options['perpost'] = $input['perpost']; $options['relnofollow'] = $input['relnofollow']; return $options; } // End options_validate() // Options page function options_page() { // Make sure the user has permissions to access the plugin options if ( ! current_user_can( 'manage_options' ) ) { wp_die( '

You do not have sufficient privileges to access this page.' ); } ?>

Debug Info

Please copy and paste the information below when reporting issues, and when requested in the support forums.

Site URL:
WordPress version:
Plugin version:
Multisite enabled:
Server software:
PHP version:
spinner, // Meta box title array( $this, 'metabox' ), // Meta box callback (outputs the HTML for the meta box) $screen, // Post types where this meta box should be used 'normal', // Context (placement) on the edit screen 'high' // Priority within the specified context ); } } // End add_metabox() // Scripts and stylesheets for use with the meta box function add_metabox_scripts() { // Custom stylesheet for meta box wp_enqueue_style( self::ID . '-metabox', // Stylesheet hook name plugins_url( 'admin/assets/css/edit-post.css', $this->pluginfile ), // URL for stylesheet array(), // Style dependencies self::VERSION // Plugin version ); /* Add script for changing the post author */ wp_enqueue_script( self::ID . '-edit-post', // Registered script handle plugins_url( 'admin/assets/js/edit-post.js', $this->pluginfile ), // URL to script array( // Script dependencies 'jquery' ), self::VERSION // Plugin version ); // Localize the script for AJAX calls wp_localize_script( self::ID . '-edit-post', // Name of script call being localized self::PREFIX . 'edit_post', // AJAX object namespace, used to call values in the JS file array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), // URL for admin AJAX calls 'nonce' => wp_create_nonce( self::ID . '-edit-post-nonce' ) // Nonce to authenticate request ) ); } // End add_metabox_scripts() // Meta box function metabox( $post ) { // Retrieve current values if they exist $cc_author_meta = get_post_meta( $post->ID, '_' . self::PREFIX . 'meta', true ); // Author metadata (stored as an array) $postauthorid = $post->post_author; // Get the user ID of the post author // If any of the values are missing from the post, retrieve them from the author's global profile if ( ! $cc_author_meta ) { $postauthor = get_userdata( $postauthorid ); // Retrieve the details of the post author $cc_author_meta = array(); // Initialize main array $cc_author_meta[0] = array( // Nested array for author data 'display_name' => $postauthor->display_name, // Set display name from post author's data 'description' => $postauthor->description // Set bio from the post author's data ); } // Display the meta box contents ?> $authordata->display_name, // Display name from profile 'description' => $authordata->description, // Biographical info from profile ) ); echo $authormeta; // Return the values retrieved from the database } exit; // End response. Required for callback to return a proper result. } // End change_postauthor_callback() // Save the information in the meta box function save_meta( $post_id ) { // Verify that values have been provided if ( isset( $_POST[self::PREFIX . 'meta'] ) ) { /* If JavaScript is not enabled, get the author's data from their user profile. This is because the values in the author name and bio fields will still be for the old author with JS disabled. */ if ( empty( $_POST[self::PREFIX . 'javascript'] ) ) { // Retrieve the details of the post author $postauthor = get_userdata( $_POST[self::PREFIX . 'postauthor'] ); // Initialize main array $author = array(); // Nested array for author data $author[0] = array( 'display_name' => $postauthor->display_name, // Set display name from post author's data 'description' => $postauthor->description // Set bio from the post author's data ); } // If JavaScript is enabled, use the values submitted from the meta box since they'll have been updated with the new author else { // Assign POST data to local variable $author = $_POST[self::PREFIX . 'meta']; } // Sanitize array values foreach ( $author as $authormeta ) { foreach ( $authormeta as $key => $meta ) { $authormeta['display_name'] = strip_tags( $meta ); } } // Save author metadata to post meta update_post_meta( $post_id, '_' . self::PREFIX . 'meta', $author ); // If the post author has been changed, update the post author if ( ! empty( $_POST[self::PREFIX . 'postauthor'] ) && ( $_POST[self::PREFIX . 'postauthor'] != $_POST[self::PREFIX . 'currentpostauthor'] ) ) { // Remove the 'save_post' hook before updating the post author to prevent an infinite loop remove_action( 'save_post', array( &$this, 'save_meta' ) ); wp_update_post( array( 'ID' => $post_id, // Post ID 'post_author' => $_POST[self::PREFIX . 'postauthor'] // Use the post author ID from the dropdown ) ); // Re-add the 'save_post' hook after the post author is updated add_action( 'save_post', array( &$this, 'save_meta' ) ); } /* If 'Update Profile' is enabled, save the author info to the user profile of the author */ foreach ( $author as $authormeta ) { foreach ( $authormeta as $key => $meta ) { if ( isset( $authormeta['update_profile'] ) ) { wp_update_user( array( 'ID' => $_POST[self::PREFIX . 'postauthor'], // Author user ID 'display_name' => $authormeta['display_name'], // Display name 'nickname' => $authormeta['display_name'], // Set nickname to display name 'description' => $authormeta['description'], // Biographical info ) ); } } } } } // End save_meta() /* ===== End Post/Page Editing ===== */ /* ===== WYSIWYG Editor ===== */ /** * Rich editor initilization * * @return array $settings editor settings and configuration */ function editor_initialize() { $settings = array ( 'id' => self::ID . '-user-description', 'config' => array( 'media_buttons' => false, // Don't display media upload button 'teeny' => true, // Keep editor to minimal button options, instead of full editor 'textarea_rows' => 5, // Number of rows in editor 'tinymce' => array( 'toolbar1' => 'bold,italic,underline,strikethrough,link,unlink', // TinyMCE 4.0+: Only show the listed buttons in the editor 'theme_advanced_buttons1' => 'bold,italic,underline,strikethrough,link,unlink' // Legacy TinyMCE setting ) ) ); return $settings; } // editor_initialize() /** * Editor for posts and pages * * @param string $content the author biographical info * @param integer $editor_id the HTML ID for the editor * @param string $textarea_name the HTML name for the textarea */ function editor( $editor_id, $textarea_name, $content = null ) { // Initialize the editor $settings = $this->editor_initialize(); // If TinyMCE is available and the user can rich edit, use TinyMCE. Otherwise, use a standard textarea. if ( function_exists( 'wp_editor' ) && user_can_richedit() ) { // Filter the author description $content = apply_filters( 'the_content', $content ); // Set 'textarea_name' in the editor settings $settings['config']['textarea_name'] = $textarea_name; // Create the editor using the provided values wp_editor( $content, $editor_id, $settings['config'] ); } // If TinyMCE can't be used, use a simple textarea else { echo ''; } } // editor() /** * Editor for user profile * * @param object $user the current user data */ function editorprofile( $user ) { // Check to make sure the user can use the rich editor if ( user_can_richedit() ) { // Initialize the editor $settings = $this->editor_initialize(); ?>
ID, 'description', true); $description = apply_filters( 'the_content', $description ); wp_editor( $description, 'description', $settings['config'] ); ?> Share a little biographical information to fill out your profile. This may be shown publicly.
pluginfile ), // Location of script 'jquery', // Dependencies self::VERSION, // Use plugin version number true // Whether to load script in footer ); } } // profilejs() /* ===== End WYSIWYG Editor ===== */ /* ===== Admin initialization ===== */ // Initialize the admin class protected function admin_initialize() { // Run plugin upgrade $this->upgrade(); } // End admin_initialize() // Plugin upgrade function upgrade() { // Check whether the database-stored plugin version number is less than the current plugin version number, or whether there is no plugin version saved in the database if ( ! empty( $this->options ) && version_compare( $this->options['dbversion'], self::VERSION, '<' ) ) { // Set local variable for options $options = $this->options; // Remove the option for toggling the WYSIWYG editor if it's present if ( isset( $options['wysiwyg'] ) ) { unset( $options['wysiwyg'] ); } /* Update the plugin version saved in the database (always the last step of the upgrade process) */ // Set the value of the plugin version $options['dbversion'] = self::VERSION; // Save to the database update_option( self::PREFIX . 'options', $options ); /* End update plugin version */ } /* If the deprecated options entries are present, we need to retrieve those values and assign them to the new structure. This upgrade process has to fall outside the standard upgrade version validation since the new options structure is not present if the old options structure is present, and therefore would never actually be executed. */ if ( get_option( self::PREFIX . 'postpage' ) ) { // Retrieve the current options from the database $postpage = get_option( 'cc_author_postpage' ); $adminoptions = get_option( 'cc_author_admin_options' ); // Set up the new options structure with old values $options = array ( 'perpost' => $postpage['perpost'], // Save author info to each individual post, rather than pulling from global author data 'relnofollow' => $postpage['relnofollow'], // Add rel="nofollow" to links in bio entries 'dbversion' => self::VERSION // Save the current plugin version ); // Save options to the database add_option( self::PREFIX . 'options', $options ); // Delete the old options entries from the database delete_option( 'cc_author_postpage' ); delete_option( 'cc_author_admin_options' ); } } // End upgrade() /* ===== End Admin Initialization ===== */ /* ===== Plugin activation and deactivation methods ===== */ // Plugin activation public function activate() { // Check WordPress version for plugin compatibility if ( version_compare( get_bloginfo( 'version' ), self::WPVER, '<' ) ) { wp_die( 'Your version of WordPress is too old to use this plugin. Please upgrade to the latest version of WordPress.' ); } // Set options for plugin $options = array ( 'perpost' => 'yes', // Save author info to each individual post, rather than pulling from global author data 'relnofollow' => 'yes', // Add rel="nofollow" to links in bio entries 'dbversion' => self::VERSION // Save the current plugin version ); add_option( self::PREFIX . 'options', $options ); // Save options to database } // End activate() // Plugin deactivation public function deactivate() { // Remove the plugin options from the database delete_option( self::PREFIX . 'options' ); } // End deactivate() /* ===== End plugin activation and deactivation methods ===== */ } /** * End cc_author_admin **/ ?>