From df2f6502722d9cd9016ea8febb36aaba47b6ea92 Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Fri, 22 Dec 2023 18:07:27 -0300 Subject: [PATCH] remove guest authors feature --- js/guest-authors.js | 32 - php/class-coauthors-guest-authors.php | 1655 ------------------------- php/class-coauthors-plus.php | 260 +--- php/class-coauthors-wp-list-table.php | 304 ----- php/class-wp-cli.php | 234 ---- template-tags.php | 52 +- 6 files changed, 40 insertions(+), 2497 deletions(-) delete mode 100644 js/guest-authors.js delete mode 100644 php/class-coauthors-guest-authors.php delete mode 100755 php/class-coauthors-wp-list-table.php diff --git a/js/guest-authors.js b/js/guest-authors.js deleted file mode 100644 index 173108bd..00000000 --- a/js/guest-authors.js +++ /dev/null @@ -1,32 +0,0 @@ -jQuery( document ).ready(function( $ ){ - $( '.reassign-option' ).on( 'click',function(){ - $( '#wpbody-content input#submit' ).addClass( 'button-primary' ).removeAttr( 'disabled' ); - }); - $( '#leave-assigned-to' ).select2({ - minimumInputLength: 2, - width: 'copy', - multiple: false, - ajax: { - url: ajaxurl, - dataType: 'json', - data: function( term, page ) { - return { - q: term, - action: 'search_coauthors_to_assign', - guest_author: $( '#id' ).val() - }; - }, - results: function( data, page ) { - return { results: data }; - } - }, - formatResult: function( object, container, query ) { - return object.display_name; - }, - formatSelection: function( object, container ) { - return object.display_name; - } - }).on( 'change', function() { - $( '#reassign-another' ).trigger( 'click' ); - }); -}); \ No newline at end of file diff --git a/php/class-coauthors-guest-authors.php b/php/class-coauthors-guest-authors.php deleted file mode 100644 index 5ba9047b..00000000 --- a/php/class-coauthors-guest-authors.php +++ /dev/null @@ -1,1655 +0,0 @@ -parent_page = apply_filters( 'coauthors_guest_author_parent_page', $this->parent_page ); - - // Allow users to change the required cap for modifying guest authors - $this->list_guest_authors_cap = apply_filters( 'coauthors_guest_author_manage_cap', $this->list_guest_authors_cap ); - - // Set up default labels, but allow themes to modify - $this->labels = apply_filters( - 'coauthors_guest_author_labels', - array( - 'singular' => __( 'Guest Author', 'co-authors-plus' ), - 'plural' => __( 'Guest Authors', 'co-authors-plus' ), - 'all_items' => __( 'All Guest Authors', 'co-authors-plus' ), - 'add_new_item' => __( 'Add New Guest Author', 'co-authors-plus' ), - 'edit_item' => __( 'Edit Guest Author', 'co-authors-plus' ), - 'new_item' => __( 'New Guest Author', 'co-authors-plus' ), - 'view_item' => __( 'View Guest Author', 'co-authors-plus' ), - 'search_items' => __( 'Search Guest Authors', 'co-authors-plus' ), - 'not_found' => __( 'No guest authors found', 'co-authors-plus' ), - 'not_found_in_trash' => __( 'No guest authors found in Trash', 'co-authors-plus' ), - 'update_item' => __( 'Update Guest Author', 'co-authors-plus' ), - 'metabox_about' => __( 'About the guest author', 'co-authors-plus' ), - 'featured_image' => __( 'Avatar', 'co-authors-plus' ), - 'set_featured_image' => __( 'Set Avatar', 'co-authors-plus' ), - 'use_featured_image' => __( 'Use Avatar', 'co-authors-plus' ), - 'remove_featured_image' => __( 'Remove Avatar', 'co-authors-plus' ), - ) - ); - - // Register a post type to store our guest authors - $args = array( - 'label' => $this->labels['singular'], - 'labels' => array( - 'name' => isset( $this->labels['plural'] ) ? $this->labels['plural'] : '', - 'singular_name' => isset( $this->labels['singular'] ) ? $this->labels['singular'] : '', - 'add_new' => _x( 'Add New', 'guest author', 'co-authors-plus' ), - 'all_items' => isset( $this->labels['all_items'] ) ? $this->labels['all_items'] : '', - 'add_new_item' => isset( $this->labels['add_new_item'] ) ? $this->labels['add_new_item'] : '', - 'edit_item' => isset( $this->labels['edit_item'] ) ? $this->labels['edit_item'] : '', - 'new_item' => isset( $this->labels['new_item'] ) ? $this->labels['new_item'] : '', - 'view_item' => isset( $this->labels['view_item'] ) ? $this->labels['view_item'] : '', - 'search_items' => isset( $this->labels['search_items'] ) ? $this->labels['search_items'] : '', - 'not_found' => isset( $this->labels['not_found'] ) ? $this->labels['not_found'] : '', - 'not_found_in_trash' => isset( $this->labels['not_found_in_trash'] ) ? $this->labels['not_found_in_trash'] : '', - 'featured_image' => isset( $this->labels['featured_image'] ) ? $this->labels['featured_image'] : '', - 'set_featured_image' => isset( $this->labels['set_featured_image'] ) ? $this->labels['set_featured_image'] : '', - 'use_featured_image' => isset( $this->labels['use_featured_image'] ) ? $this->labels['use_featured_image'] : '', - 'remove_featured_image' => isset( $this->labels['remove_featured_image'] ) ? $this->labels['remove_featured_image'] : '', - ), - 'public' => true, - 'publicly_queryable' => false, - 'exclude_from_search' => true, - 'show_in_menu' => false, - 'show_in_rest' => true, - 'supports' => array( - 'thumbnail', - ), - 'taxonomies' => array( - $coauthors_plus->coauthor_taxonomy, - ), - 'rewrite' => false, - 'query_var' => false, - ); - register_post_type( $this->post_type, $args ); - - // Hacky way to remove the title and the editor - remove_post_type_support( $this->post_type, 'title' ); - remove_post_type_support( $this->post_type, 'editor' ); - - } - - /** - * Filter the messages that appear when saving or updating a guest author - * - * @since 3.0 - */ - public function filter_post_updated_messages( $messages ) { - global $post; - - if ( $this->post_type !== $post->post_type ) { - return $messages; - } - - $guest_author = $this->get_guest_author_by( 'ID', $post->ID ); - $guest_author_link = $this->filter_author_link( '', $guest_author->ID, $guest_author->user_nicename ); - - $messages[ $this->post_type ] = array( - 0 => '', // Unused. Messages start at index 1. - /* translators: Guest author URL */ - 1 => sprintf( __( 'Guest author updated. View profile', 'co-authors-plus' ), esc_url( $guest_author_link ) ), - 2 => __( 'Custom field updated.', 'co-authors-plus' ), - 3 => __( 'Custom field deleted.', 'co-authors-plus' ), - 4 => __( 'Guest author updated.', 'co-authors-plus' ), - /* translators: %s: date and time of the revision */ - 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Guest author restored to revision from %s', 'co-authors-plus' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - /* translators: Guest author URL */ - 6 => sprintf( __( 'Guest author updated. View profile', 'co-authors-plus' ), esc_url( $guest_author_link ) ), - 7 => __( 'Guest author saved.', 'co-authors-plus' ), - /* translators: Guest author URL */ - 8 => sprintf( __( 'Guest author submitted. Preview profile', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ), - 9 => sprintf( - /* translators: Guest author profile preview URL. */ - __( 'Guest author scheduled for: %1$s. Preview profile', 'co-authors-plus' ), - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i', 'co-authors-plus' ), strtotime( $post->post_date ) ), - esc_url( $guest_author_link ) - ), - /* translators: Guest author profile preview URL. */ - 10 => sprintf( __( 'Guest author updated. Preview profile', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ), - ); - return $messages; - } - - /** - * Handle the admin action to create a guest author based - * on an existing user - * - * @since 3.0 - */ - public function handle_create_guest_author_action() { - - if ( ! isset( $_GET['action'], $_GET['nonce'], $_GET['user_id'] ) || 'cap-create-guest-author' !== $_GET['action'] ) { - return; - } - - if ( ! wp_verify_nonce( $_GET['nonce'], 'create-guest-author' ) ) { - wp_die( esc_html__( "Doin' something fishy, huh?", 'co-authors-plus' ) ); - } - - if ( ! current_user_can( $this->list_guest_authors_cap ) ) { - wp_die( esc_html__( "You don't have permission to perform this action.", 'co-authors-plus' ) ); - } - - $user_id = (int) $_GET['user_id']; - - // Create the guest author - $post_id = $this->create_guest_author_from_user_id( $user_id ); - if ( is_wp_error( $post_id ) ) { - wp_die( esc_html( $post_id->get_error_message() ) ); - } - - do_action( 'cap_guest_author_create' ); - - // Redirect to the edit Guest Author screen - $edit_link = get_edit_post_link( $post_id, 'redirect' ); - $redirect_to = add_query_arg( 'message', 'guest-author-created', $edit_link ); - wp_safe_redirect( esc_url_raw( $redirect_to ) ); - exit; - - } - - /** - * Handle the admin action to delete a guest author and possibly reassign their posts - * - * @since 3.0 - */ - public function handle_delete_guest_author_action() { - global $coauthors_plus; - - if ( ! isset( $_POST['action'], $_POST['reassign'], $_POST['_wpnonce'], $_POST['id'] ) || 'delete-guest-author' != $_POST['action'] ) { - return; - } - - // Verify the user is who they say they are - if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'delete-guest-author' ) ) { - wp_die( esc_html__( "Doin' something fishy, huh?", 'co-authors-plus' ) ); - } - - // Make sure they can perform the action - if ( ! current_user_can( $this->list_guest_authors_cap ) ) { - wp_die( esc_html__( "You don't have permission to perform this action.", 'co-authors-plus' ) ); - } - - // Make sure the guest author actually exists - $guest_author = $this->get_guest_author_by( 'ID', (int) $_POST['id'] ); - if ( ! $guest_author ) { - wp_die( esc_html__( "Guest author can't be deleted because it doesn't exist.", 'co-authors-plus' ) ); - } - - // Perform the reassignment if needed - $guest_author_term = $coauthors_plus->get_author_term( $guest_author ); - switch ( $_POST['reassign'] ) { - // Leave assigned to the current linked account - case 'leave-assigned': - $reassign_to = $guest_author->linked_account; - break; - // Reassign to a different user - case 'reassign-another': - if ( isset( $_POST['leave-assigned-to'] ) ) { - $user_nicename = sanitize_title( $_POST['leave-assigned-to'] ); - $reassign_to = $coauthors_plus->get_coauthor_by( 'user_nicename', $user_nicename ); - if ( ! $reassign_to ) { - wp_die( esc_html__( 'Co-author does not exists. Try again?', 'co-authors-plus' ) ); - } - $reassign_to = $reassign_to->user_login; - } - break; - // Remove the byline, but don't delete the post - case 'remove-byline': - $reassign_to = false; - break; - default: - wp_die( esc_html__( 'Please make sure to pick an option.', 'co-authors-plus' ) ); - } - - $retval = $this->delete( $guest_author->ID, $reassign_to ); - - $args = array( - 'page' => 'view-guest-authors', - ); - if ( is_wp_error( $retval ) ) { - $args['message'] = 'delete-error'; - } else { - $args['message'] = 'guest-author-deleted'; - - do_action( 'cap_guest_author_del' ); - } - - // Redirect to safety - $redirect_to = add_query_arg( array_map( 'rawurlencode', $args ), admin_url( $this->parent_page ) ); - wp_safe_redirect( esc_url_raw( $redirect_to ) ); - exit; - } - - /** - * Given a search query, suggest some co-authors that might match it - * - * @since 3.0 - */ - public function handle_ajax_search_coauthors_to_assign() { - global $coauthors_plus; - - if ( ! current_user_can( $this->list_guest_authors_cap ) ) { - die(); - } - - if ( ! isset( $_GET['q'] ) ) { - die(); - } - - $search = sanitize_text_field( $_GET['q'] ); - if ( ! empty( $_GET['guest_author'] ) ) { - $ignore = array( $this->get_guest_author_by( 'ID', (int) $_GET['guest_author'] )->user_login ); - } else { - $ignore = array(); - } - - $results = wp_list_pluck( $coauthors_plus->search_authors( $search, $ignore ), 'user_login' ); - $retval = array(); - foreach ( $results as $user_login ) { - $coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $user_login ); - $retval[] = (object) array( - 'display_name' => $coauthor->display_name, - 'user_login' => $coauthor->user_login, - 'id' => $coauthor->user_nicename, - ); - } - echo wp_json_encode( $retval ); - die(); - } - - - /** - * Some redirection we need to do for linked accounts - * - * @todo support author ID query vars - */ - public function action_parse_request( $query ) { - - if ( ! isset( $query->query_vars['author_name'] ) ) { - return $query; - } - - // No redirection needed on admin requests - if ( is_admin() ) { - return $query; - } - - $coauthor = $this->get_guest_author_by( 'linked_account', sanitize_title( $query->query_vars['author_name'] ) ); - if ( is_object( $coauthor ) && $query->query_vars['author_name'] != $coauthor->user_login ) { - global $wp_rewrite; - $link = $wp_rewrite->get_author_permastruct(); - - if ( empty( $link ) ) { - $file = home_url( '/' ); - $link = $file . '?author_name=' . $coauthor->user_login; - } else { - $link = home_url( user_trailingslashit( str_replace( '%author%', $coauthor->user_login, $link ) ) ); - } - wp_safe_redirect( $link ); - exit; - } - - return $query; - } - - /** - * Add the admin menus for seeing all co-authors - * - * @since 3.0 - */ - public function action_admin_menu() { - - add_submenu_page( $this->parent_page, $this->labels['plural'], $this->labels['plural'], $this->list_guest_authors_cap, 'view-guest-authors', array( $this, 'view_guest_authors_list' ) ); - - } - - /** - * Enqueue any scripts or styles used for Guest Authors - * - * @since 3.0 - */ - public function action_admin_enqueue_scripts() { - global $pagenow; - // Enqueue our guest author CSS on the related pages - if ( $this->parent_page === $pagenow && isset( $_GET['page'] ) && 'view-guest-authors' === $_GET['page'] ) { - wp_enqueue_script( 'jquery-select2', plugins_url( 'lib/select2/select2.min.js', __DIR__ ), array( 'jquery' ), COAUTHORS_PLUS_VERSION ); - wp_enqueue_style( 'cap-jquery-select2-css', plugins_url( 'lib/select2/select2.css', __DIR__ ), false, COAUTHORS_PLUS_VERSION ); - - wp_enqueue_style( 'guest-authors-css', plugins_url( 'css/guest-authors.css', __DIR__ ), false, COAUTHORS_PLUS_VERSION ); - wp_enqueue_script( 'guest-authors-js', plugins_url( 'js/guest-authors.js', __DIR__ ), false, COAUTHORS_PLUS_VERSION ); - } elseif ( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) && $this->post_type === get_post_type() ) { - add_action( 'admin_head', array( $this, 'change_title_icon' ) ); - } - } - - /** - * Change the icon appearing next to the title - * Core doesn't allow us to filter screen_icon(), so changing the ID is the next best thing - * - * @since 3.0.1 - */ - public function change_title_icon() { - ?> - - parent_page != $pagenow || ! isset( $_REQUEST['message'] ) ) { - return; - } - - $message = $_REQUEST['message'] === 'guest-author-deleted' ? __( 'Guest author deleted.', 'co-authors-plus' ) : false; - - if ( $message ) { - echo '

' . esc_html( $message ) . '

'; - } - } - - /** - * Register the meta boxes used for Guest Authors. - * - * @since 3.0 - */ - public function action_add_meta_boxes() { - global $coauthors_plus; - - if ( get_post_type() == $this->post_type ) { - // Remove the submitpost meta box because we have our own. - remove_meta_box( 'submitdiv', $this->post_type, 'side' ); - remove_meta_box( 'slugdiv', $this->post_type, 'normal' ); - add_meta_box( 'coauthors-manage-guest-author-save', __( 'Save', 'co-authors-plus' ), array( $this, 'metabox_manage_guest_author_save' ), $this->post_type, 'side' ); - add_meta_box( 'coauthors-manage-guest-author-slug', __( 'Unique Slug', 'co-authors-plus' ), array( $this, 'metabox_manage_guest_author_slug' ), $this->post_type, 'side' ); - // Our meta boxes with co-author details. - add_meta_box( 'coauthors-manage-guest-author-name', __( 'Name', 'co-authors-plus' ), array( $this, 'metabox_manage_guest_author_name' ), $this->post_type, 'normal' ); - add_meta_box( 'coauthors-manage-guest-author-contact-info', __( 'Contact Info', 'co-authors-plus' ), array( $this, 'metabox_manage_guest_author_contact_info' ), $this->post_type, 'normal' ); - add_meta_box( 'coauthors-manage-guest-author-bio', $this->labels['metabox_about'], array( $this, 'metabox_manage_guest_author_bio' ), $this->post_type, 'normal' ); - } - } - - /** - * View a list table of all guest authors - * - * @since 3.0 - */ - public function view_guest_authors_list() { - - // Allow guest authors to be deleted - if ( isset( $_GET['action'], $_GET['id'], $_GET['_wpnonce'] ) && 'delete' == $_GET['action'] ) { - // Make sure the user is who they say they are - if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'guest-author-delete' ) ) { - wp_die( esc_html__( "Doin' something fishy, huh?", 'co-authors-plus' ) ); - } - - // Make sure the guest author actually exists - $guest_author = $this->get_guest_author_by( 'ID', (int) $_GET['id'] ); - if ( ! $guest_author ) { - wp_die( esc_html__( "Guest author can't be deleted because it doesn't exist.", 'co-authors-plus' ) ); - } - - // get post count - global $coauthors_plus; - $count = $coauthors_plus->get_guest_author_post_count( $guest_author ); - - echo '
'; - echo '

' . esc_html__( 'Delete Guest Authors', 'co-authors-plus' ) . '

'; - echo '
'; - echo '

' . esc_html__( 'You have specified this guest author for deletion:', 'co-authors-plus' ) . '

'; - echo '

#' . esc_html( $guest_author->ID . ': ' . $guest_author->display_name ) . '

'; - // display wording differently per post count - if ( 0 === $count ) { - $post_count_message = '

' . esc_html__( 'There are no posts associated with this guest author.', 'co-authors-plus' ) . '

'; - } else { - $note = '

' . __( "Note: If you'd like to delete the guest author and all of their posts, you should delete their posts first and then come back to delete the guest author.", 'co-authors-plus' ) . '

'; - $post_count_message_text = sprintf( - /* translators: Count of posts */ - _n( - 'There is %d post associated with this guest author. What should be done with the post assigned to this Guest Author?', - 'There are %d posts associated with this guest author. What should be done with the posts assigned to this Guest Author?', - $count, - 'co-authors-plus' - ), - number_format_i18n( $count ) - ); - $post_count_message = '

' . $post_count_message_text . '

' . $note; - } - $allowed_html = array( - 'p' => array( - 'class' => array(), - ), - ); - echo wp_kses( $post_count_message, $allowed_html ); - echo '
'; - // Hidden stuffs - echo ''; - wp_nonce_field( 'delete-guest-author' ); - echo ''; - echo '
    '; - // only show delete options if post count > 0 - if ( $count > 0 ) { - // Reassign to another user - echo '
  • '; - echo ''; - echo '
  • '; - // Leave mapped to a linked account - if ( get_user_by( 'login', $guest_author->linked_account ) ) { - echo '
  • '; - } - // Remove bylines from the posts - echo '
  • '; - } else { - echo ''; - } - echo '
'; - // disable disabled submit button for 0 post count - if ( 0 === $count ) { - submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary' ); - } else { - submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary', 'submit', true, array( 'disabled' => 'disabled' ) ); - } - echo '
'; - echo '
'; - } else { - ?> -
-

- add_guest_author_cap ) ) { - $add_new_url = admin_url( "post-new.php?post_type={$this->post_type}" ); - ?> -
-
- - prepare_items(); - $cap_list_table->display(); - ?> -
-
- post_status, array( 'pending', 'publish', 'draft' ) ) ) { - $button_text = $this->labels['update_item']; - } else { - $button_text = $this->labels['add_new_item']; - } - submit_button( $button_text, 'primary', 'publish', false ); - - // Secure all of our requests - wp_nonce_field( 'guest-author-nonce', 'guest-author-nonce' ); - - } - - /** - * Meta box for editing this guest author's slug or changing the linked account - * - * @since 3.0 - */ - public function metabox_manage_guest_author_slug() { - global $post; - - $pm_key = $this->get_post_meta_key( 'user_login' ); - $existing_slug = get_post_meta( $post->ID, $pm_key, true ); - - echo ''; - - // Taken from grist_authors. - $linked_account_key = $this->get_post_meta_key( 'linked_account' ); - $linked_account = get_post_meta( $post->ID, $linked_account_key, true ); - if ( $user = get_user_by( 'login', $linked_account ) ) { - $linked_account_id = $user->ID; - } else { - $linked_account_id = -1; - } - - // If user_login is the same as linked account, don't let the association be removed - if ( $linked_account == $existing_slug ) { - add_filter( 'wp_dropdown_users', array( $this, 'filter_wp_dropdown_users_to_disable' ) ); - } - - $linked_account_user_ids = wp_list_pluck( $this->get_all_linked_accounts(), 'ID' ); - if ( false !== ( $key = array_search( $linked_account_id, $linked_account_user_ids ) ) ) { - unset( $linked_account_user_ids[ $key ] ); - } - - echo '

'; - wp_dropdown_users( - apply_filters( - 'coauthors_guest_author_linked_account_args', - array( - 'show_option_none' => __( '-- Not mapped --', 'co-authors-plus' ), - 'name' => esc_attr( $this->get_post_meta_key( 'linked_account' ) ), - // If we're adding an author or if there is no post author (0), then use -1 (which is show_option_none). - // We then take -1 on save and convert it back to 0. (#blamenacin) - 'selected' => $linked_account_id, - // Don't let user accounts to be linked to more than one guest author - 'exclude' => $linked_account_user_ids, - ) - ) - ); - echo '

'; - - remove_filter( 'wp_dropdown_users', array( $this, 'filter_wp_dropdown_users_to_disable' ) ); - } - - /** - * Make a wp_dropdown_users disabled - * Only applied if the user_login value for the guest author matches its linked account - * - * @since 3.0 - */ - public function filter_wp_dropdown_users_to_disable( $output ) { - return str_replace( ''; - } else { - echo ''; - } - echo ''; - } - echo ''; - - } - - /** - * Meta box to display all the pertinent contact details for a Guest Author not linked to - * user account. - * - * @since 3.0 - */ - public function metabox_manage_guest_author_contact_info() { - global $post; - - $fields = $this->get_guest_author_fields( 'contact-info' ); - echo ''; - foreach ( $fields as $field ) { - $pm_key = $this->get_post_meta_key( $field['key'] ); - $value = get_post_meta( $post->ID, $pm_key, true ); - echo ''; - } - echo '
'; - echo ''; - echo ''; - - if ( ! isset( $field['input'] ) ) { - $field['input'] = 'text'; - } - $field['input'] = apply_filters( 'coauthors_name_field_type_' . $pm_key, $field['input'] ); - if ( $field['input'] === 'checkbox' ) { - echo ''; - } else { - echo ''; - } - - echo '
'; - - } - - /** - * Meta box to edit the bio and other biographical details of the Guest Author. - * - * @since 3.0 - */ - public function metabox_manage_guest_author_bio() { - global $post; - - $fields = $this->get_guest_author_fields( 'about' ); - echo ''; - foreach ( $fields as $field ) { - $pm_key = $this->get_post_meta_key( $field['key'] ); - $value = get_post_meta( $post->ID, $pm_key, true ); - printf( - ' - - - - - ', - esc_attr( $pm_key ), - esc_html( $field['label'] ), - esc_attr( $pm_key ), - esc_textarea( $value ) - ); - } - echo '
- - - -
'; - - } - - /** - * When a guest author is created or updated, we need to properly create - * the post_name based on some data provided by the user - * - * @since 3.0 - */ - public function manage_guest_author_filter_post_data( $post_data, $original_args ) { - - if ( $post_data['post_type'] != $this->post_type ) { - return $post_data; - } - - // @todo caps check - if ( ! isset( $_POST['guest-author-nonce'] ) || ! wp_verify_nonce( $_POST['guest-author-nonce'], 'guest-author-nonce' ) ) { - return $post_data; - } - - // Validate the display name - if ( empty( $_POST['cap-display_name'] ) ) { - wp_die( esc_html__( 'Guest authors cannot be created without display names.', 'co-authors-plus' ) ); - } - $post_data['post_title'] = sanitize_text_field( $_POST['cap-display_name'] ); - - $slug = sanitize_title( get_post_meta( $original_args['ID'], $this->get_post_meta_key( 'user_login' ), true ) ); - if ( ! $slug ) { - $slug = sanitize_title( $_POST['cap-display_name'] ); - } - - // Uh oh, no guest authors without slugs - if ( ! $slug ) { - wp_die( esc_html__( 'Guest authors cannot be created without display names.', 'co-authors-plus' ) ); - } - $post_data['post_name'] = $this->get_post_meta_key( $slug ); - - // Guest authors can't be created with the same user_login as a user - $user_nicename = str_replace( 'cap-', '', $slug ); - $user = get_user_by( 'slug', $user_nicename ); - if ( $user - && is_user_member_of_blog( $user->ID, get_current_blog_id() ) - && $user->user_login != get_post_meta( $original_args['ID'], $this->get_post_meta_key( 'linked_account' ), true ) ) { - // if user has selected to link account to matching user we don't have to bail - if ( isset( $_POST['cap-linked_account'] ) && (int) $_POST['cap-linked_account'] === $user->ID ) { - return $post_data; - } - wp_die( esc_html__( 'There is a WordPress user with the same username as this guest author, please go back and link them in order to update.', 'co-authors-plus' ) ); - } - - // Guest authors can't have the same post_name value - $guest_author = $this->get_guest_author_by( 'post_name', $post_data['post_name'] ); - if ( $guest_author && $guest_author->ID != $original_args['ID'] ) { - wp_die( esc_html__( 'Display name conflicts with another guest author display name.', 'co-authors-plus' ) ); - } - - return $post_data; - } - - /** - * Save the various meta fields associated with our guest author model - * - * @since 3.0 - */ - public function manage_guest_author_save_meta_fields( $post_id, $post ) { - global $coauthors_plus; - - if ( $post->post_type != $this->post_type ) { - return; - } - - // @todo caps check - if ( ! isset( $_POST['guest-author-nonce'] ) || ! wp_verify_nonce( $_POST['guest-author-nonce'], 'guest-author-nonce' ) ) { - return; - } - - // Save our data to post meta - $author_fields = $this->get_guest_author_fields(); - foreach ( $author_fields as $author_field ) { - - $key = $this->get_post_meta_key( $author_field['key'] ); - // 'user_login' should only be saved on post update if it doesn't exist - if ( 'user_login' == $author_field['key'] && ! get_post_meta( $post_id, $key, true ) ) { - $display_name_key = $this->get_post_meta_key( 'display_name' ); - $temp_slug = sanitize_title( $_POST[ $display_name_key ] ); // phpcs:ignore - update_post_meta( $post_id, $key, $temp_slug ); - continue; - } - if ( 'linked_account' == $author_field['key'] ) { - $linked_account_key = $this->get_post_meta_key( 'linked_account' ); - if ( ! empty( $_POST[ $linked_account_key ] ) ) { - $user_id = (int) $_POST[ $linked_account_key ]; - } else { - continue; - } - $user = get_user_by( 'id', $user_id ); - if ( $user_id > 0 && is_object( $user ) ) { - $user_login = $user->user_login; - } else { - $user_login = ''; - } - update_post_meta( $post_id, $key, $user_login ); - continue; - } - - if ( isset( $author_field['input'] ) && 'checkbox' === $author_field['input'] && ! isset( $_POST[ $key ] ) ) { - delete_post_meta( $post_id, $key ); - } - - if ( ! isset( $_POST[ $key ] ) ) { - continue; - } - - if ( isset( $author_field['sanitize_function'] ) && is_callable( $author_field['sanitize_function'] ) ) { - $value = call_user_func( $author_field['sanitize_function'], $_POST[ $key ] ); - } else { - $value = sanitize_text_field( $_POST[ $key ] ); - } - update_post_meta( $post_id, $key, $value ); - } - - $author = $this->get_guest_author_by( 'ID', $post_id ); - $author_term = $coauthors_plus->update_author_term( $author ); - // Add the author as a post term - wp_set_post_terms( $post_id, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy ); - - // Explicitly clear all caches, to remove negative caches that may have existed prior to this - // Guest Author's creation / update - $this->delete_guest_author_cache( $post_id ); - } - - /** - * Return a simulated WP_User object based on the post ID - * of a guest author - * - * @since 3.0 - * - * @param string $key Key to search by (login,email) - * @param string $value Value to search for - * @param object|false $coauthor The guest author on success, false on failure - */ - public function get_guest_author_by( $key, $value, $force = false ) { - global $wpdb; - - $cache_key = $this->get_cache_key( $key, $value ); - - if ( ! $force && false !== ( $retval = wp_cache_get( $cache_key, self::$cache_group ) ) ) { - // Properly catch our false condition cache - if ( is_object( $retval ) ) { - return $retval; - } - - return false; - } - - switch ( $key ) { - case 'ID': - case 'id': - $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID=%d AND post_type = %s", $value, $this->post_type ); - $post_id = $wpdb->get_var( $query ); // phpcs:ignore - if ( empty( $post_id ) ) { - $post_id = '0'; - } - break; - case 'user_nicename': - case 'post_name': - $value = $this->get_post_meta_key( $value ); - $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name=%s AND post_type = %s", $value, $this->post_type ); - $post_id = $wpdb->get_var( $query ); // phpcs:ignore - if ( empty( $post_id ) ) { - $post_id = '0'; - } - break; - case 'login': - case 'user_login': - case 'linked_account': - case 'user_email': - if ( 'login' == $key ) { - $key = 'user_login'; - } - // Ensure we aren't doing the lookup by the prefixed value - if ( 'user_login' == $key ) { - $value = preg_replace( '#^cap\-#', '', sanitize_title_for_query( $value ) ); - } - $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value=%s;", $this->get_post_meta_key( $key ), $value ); - $post_id = $wpdb->get_var( $query ); // phpcs:ignore - if ( empty( $post_id ) ) { - if ( 'user_login' == $key ) { - return $this->get_guest_author_by( 'post_name', $value ); // fallback to post_name in case the guest author isn't a linked account - } - $post_id = '0'; - } - break; - default: - $post_id = '0'; - break; - } - - if ( ! $post_id ) { - // Best hacky way to cache the false condition - wp_cache_set( $cache_key, '0', self::$cache_group ); - return false; - } - - $guest_author = array( - 'ID' => $post_id, - ); - - // Load the guest author fields - $fields = $this->get_guest_author_fields(); - foreach ( $fields as $field ) { - $key = $field['key']; - $pm_key = $this->get_post_meta_key( $field['key'] ); - $guest_author[ $key ] = get_post_meta( $post_id, $pm_key, true ); - } - // Support for non-Latin characters. They're stored as urlencoded slugs - $guest_author['user_login'] = urldecode( $guest_author['user_login'] ); - - // Hack to model the WP_User object - $guest_author['user_nicename'] = sanitize_title( $guest_author['user_login'] ); - $guest_author['type'] = 'guest-author'; - - if ( ! isset( $guest_author['nickname'] ) ) { - $guest_author['nickname'] = ''; - } - - wp_cache_set( $cache_key, (object) $guest_author, self::$cache_group ); - - return (object) $guest_author; - } - - /** - * Get a thumbnail for a Guest Author object. - * - * @param object The Guest Author object for which to retrieve the thumbnail. - * @param int The desired image size. - * @param array|string Optional. An array or string of additional classes. Default null. - * @return string The thumbnail image tag, or null if one doesn't exist. - */ - public function get_guest_author_thumbnail( $guest_author, $size, $class = null ) { - // See if the guest author has an avatar - if ( ! has_post_thumbnail( $guest_author->ID ) ) { - return null; - } - - $args = array( - 'class' => "avatar avatar-{$size} photo", - ); - if ( ! empty( $class ) ) { - if ( is_array( $class ) ) { - $class = implode( ' ', $class ); - } - $args['class'] .= " $class"; - } - - $size = array( $size, $size ); - - $thumbnail = get_the_post_thumbnail( $guest_author->ID, $size, $args ); - - return $thumbnail; - } - - /** - * Get all the meta fields that can be associated with a guest author - * - * @since 3.0 - */ - public function get_guest_author_fields( $groups = 'all' ) { - - $groups = (array) $groups; - $global_fields = array( - // Hidden (included in object, no UI elements) - array( - 'key' => 'ID', - 'label' => __( 'ID', 'co-authors-plus' ), - 'group' => 'hidden', - 'input' => 'hidden', - ), - // Name - array( - 'key' => 'display_name', - 'label' => __( 'Display Name', 'co-authors-plus' ), - 'group' => 'name', - 'required' => true, - ), - array( - 'key' => 'first_name', - 'label' => __( 'First Name', 'co-authors-plus' ), - 'group' => 'name', - ), - array( - 'key' => 'last_name', - 'label' => __( 'Last Name', 'co-authors-plus' ), - 'group' => 'name', - ), - array( - 'key' => 'user_login', - 'label' => __( 'Slug', 'co-authors-plus' ), - 'group' => 'slug', - 'required' => true, - ), - // Contact info - array( - 'key' => 'user_email', - 'label' => __( 'E-mail', 'co-authors-plus' ), - 'group' => 'contact-info', - 'input' => 'email', - ), - array( - 'key' => 'linked_account', - 'label' => __( 'Linked Account', 'co-authors-plus' ), - 'group' => 'slug', - ), - array( - 'key' => 'website', - 'label' => __( 'Website', 'co-authors-plus' ), - 'group' => 'contact-info', - 'input' => 'url', - ), - array( - 'key' => 'description', - 'label' => __( 'Biographical Info', 'co-authors-plus' ), - 'group' => 'about', - 'sanitize_function' => 'wp_filter_post_kses', - ), - ); - $fields_to_return = array(); - foreach ( $global_fields as $single_field ) { - if ( in_array( $single_field['group'], $groups ) || 'all' === $groups[0] && 'hidden' !== $single_field['group'] ) { - $fields_to_return[] = $single_field; - } - } - - return apply_filters( 'coauthors_guest_author_fields', $fields_to_return, $groups ); - - } - - /** - * Gets a postmeta key by prefixing it with 'cap-' - * if not yet prefixed - * - * @since 3.0 - */ - public function get_post_meta_key( $key ) { - - if ( 0 !== stripos( $key, 'cap-' ) ) { - $key = 'cap-' . $key; - } - - return $key; - } - - /** - * Build a cache key for a given key/value - * - * @param string $key A guest author field - * @param string $value The guest author field value - * - * @return string The generated cache key - */ - public function get_cache_key( $key, $value ) { - // Normalize $key and $value - switch ( $key ) { - case 'post_name': - $key = 'user_nicename'; - - if ( 0 === strpos( $value, 'cap-' ) ) { - $value = substr( $value, 4 ); - } - - break; - - case 'login': - $key = 'user_login'; - - break; - } - - $cache_key = md5( 'guest-author-' . $key . '-' . $value ); - - return $cache_key; - } - - /** - * Get all the user accounts that have been linked. - * - * @since 3.0 - */ - public function get_all_linked_accounts( $force = false ) { - global $wpdb; - - $cache_key = 'all-linked-accounts'; - $retval = wp_cache_get( $cache_key, self::$cache_group ); - - if ( true === $force || false === $retval ) { - $user_logins = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value !=''", $this->get_post_meta_key( 'linked_account' ) ) ); - $users = array(); - foreach ( $user_logins as $user_login ) { - $user = get_user_by( 'login', $user_login ); - if ( ! $user ) { - continue; - } - $users[] = array( - 'ID' => $user->ID, - 'user_login' => $user->user_login, - ); - } - $retval = $users; - wp_cache_set( $cache_key, $retval, self::$cache_group ); - } - return ( $retval ) ?: array(); - } - - /** - * Filter update post metadata - * Clean caches when any of the values have been changed - * - * @since 3.0 - */ - public function filter_update_post_metadata( $retnull, $object_id, $meta_key, $meta_value, $prev_value ) { - - if ( $this->post_type != get_post_type( $object_id ) ) { - return $retnull; - } - - // If the linked_account is changing, invalidate the cache of all linked accounts - // Don't regenerate though, as we haven't saved the new value - $linked_account_key = $this->get_post_meta_key( 'linked_account' ); - if ( $linked_account_key == $meta_key && get_post_meta( $object_id, $linked_account_key, true ) !== $meta_value ) { - $this->delete_guest_author_cache( $object_id ); - } - - // If one of the guest author meta values has changed, we'll need to invalidate all keys - if ( false !== strpos( $meta_key, 'cap-' ) && get_post_meta( $object_id, $meta_key, true ) !== $meta_value ) { - $this->delete_guest_author_cache( $object_id ); - } - - return null; - } - - /** - * Delete all the cache values associated with a guest author. - * - * @since 3.0 - * - * @param int|object $guest_author The guest author ID or object - */ - public function delete_guest_author_cache( $id_or_object ) { - - if ( is_object( $id_or_object ) ) { - $guest_author = $id_or_object; - } else { - $guest_author = $this->get_guest_author_by( 'ID', $id_or_object, true ); - } - - // Delete the lookup cache associated with each old co-author value - $keys = wp_list_pluck( $this->get_guest_author_fields(), 'key' ); - array_push( $keys, 'login', 'post_name', 'user_nicename', 'ID', 'id' ); - foreach ( $keys as $key ) { - $value_key = $key; - - if ( 'post_name' == $key ) { - $value_key = 'user_nicename'; - } elseif ( 'login' == $key ) { - $value_key = 'user_login'; - } elseif ( 'id' == $key ) { - $value_key = 'ID'; - } - - $cache_key = $this->get_cache_key( $key, $guest_author->$value_key ); - - wp_cache_delete( $cache_key, self::$cache_group ); - } - - // Delete the 'all-linked-accounts' cache - wp_cache_delete( 'all-linked-accounts', self::$cache_group ); - - } - - - /** - * Create a guest author. - * - * @param $args array Author args. Required keys to create author: 'display_name' and 'user_email'. - * - * @since 3.0 - * @return int|WP_Error The ID of the created guest author, or a WP_Error object if the author could not be created. - */ - public function create( $args ) { - global $coauthors_plus; - - // Validate the arguments that have been passed - $fields = $this->get_guest_author_fields(); - foreach ( $fields as $field ) { - - // Make sure required fields are there - if ( ! empty( $field['required'] ) && empty( $args[ $field['key'] ] ) ) { - /* translators: Name of a form field. */ - return new WP_Error( 'field-required', sprintf( __( '%s is a required field', 'co-authors-plus' ), $field['key'] ) ); - } - - // The user login field shouldn't collide with any existing users - if ( 'user_login' == $field['key'] && $existing_coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $args['user_login'], true ) ) { - if ( 'guest-author' == $existing_coauthor->type ) { - return new WP_Error( 'duplicate-field', __( 'user_login cannot duplicate existing guest author or mapped user', 'co-authors-plus' ) ); - } - } - } - - // Create the primary post object - $new_post = array( - 'post_title' => $args['display_name'], - 'post_name' => sanitize_title( $this->get_post_meta_key( $args['user_login'] ) ), - 'post_type' => $this->post_type, - ); - $post_id = wp_insert_post( $new_post, true ); - if ( is_wp_error( $post_id ) ) { - return $post_id; - } - - // Add all the fields for the new guest author. - foreach ( $fields as $field ) { - $key = $field['key']; - if ( empty( $args[ $key ] ) ) { - continue; - } - $pm_key = $this->get_post_meta_key( $key ); - update_post_meta( $post_id, $pm_key, $args[ $key ] ); - } - - // Attach the avatar / featured image. - if ( ! empty( $args['avatar'] ) ) { - set_post_thumbnail( $post_id, $args['avatar'] ); - } - - // Make sure the author term exists and that we're assigning it to this post type - $author_term = $coauthors_plus->update_author_term( $this->get_guest_author_by( 'ID', $post_id ) ); - wp_set_post_terms( $post_id, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy ); - - // Explicitly clear all caches, to remove negative caches that may have existed prior to this - // Guest Author's creation - $this->delete_guest_author_cache( $post_id ); - - return $post_id; - } - - /** - * Delete a guest author - * - * @since 3.0 - * - * @param int $post_id The ID for the guest author profile - * @param string $reassign_to User login value for the co-author to reassign posts to - * @return bool|WP_Error $success True on success, WP_Error on a failure - */ - public function delete( $id, $reassign_to = false ) { - global $coauthors_plus; - - $guest_author = $this->get_guest_author_by( 'ID', $id ); - if ( ! $guest_author ) { - return new WP_Error( 'guest-author-missing', __( 'Guest author does not exist', 'co-authors-plus' ) ); - } - - $guest_author_term = $coauthors_plus->get_author_term( $guest_author ); - - if ( $reassign_to ) { - - // We're reassigning the guest author's posts user to its linked account - if ( $guest_author->linked_account == $reassign_to ) { - $reassign_to_author = get_user_by( 'login', $reassign_to ); - } else { - $reassign_to_author = $coauthors_plus->get_coauthor_by( 'user_login', $reassign_to ); - } - - if ( ! $reassign_to_author ) { - return new WP_Error( 'reassign-to-missing', __( 'Reassignment co-author does not exist', 'co-authors-plus' ) ); - } - - $reassign_to_term = $coauthors_plus->get_author_term( $reassign_to_author ); - // In the case where the guest author and its linked account shared the same term, we don't want to reassign - if ( $guest_author_term->term_id != $reassign_to_term->term_id ) { - wp_delete_term( - $guest_author_term->term_id, - $coauthors_plus->coauthor_taxonomy, - array( - 'default' => $reassign_to_term->term_id, - 'force_default' => true, - ) - ); - } - } else { - wp_delete_term( $guest_author_term->term_id, $coauthors_plus->coauthor_taxonomy ); - } - - // Delete the guest author profile - wp_delete_post( $guest_author->ID, true ); - - // Make sure all the caches are reset. - $this->delete_guest_author_cache( $guest_author ); - return true; - } - - - /** - * Create a guest author from an existing WordPress user - * - * @since 3.0 - * - * @param int $user_id ID for a WordPress user - * @return int|WP_Error $retval ID for the new guest author on success, WP_Error on failure - */ - public function create_guest_author_from_user_id( $user_id ) { - - $user = get_user_by( 'id', $user_id ); - if ( ! $user ) { - return new WP_Error( 'invalid-user', __( 'No user exists with that ID', 'co-authors-plus' ) ); - } - - $guest_author = array(); - foreach ( $this->get_guest_author_fields() as $field ) { - $key = $field['key']; - if ( ! empty( $user->$key ) ) { - $guest_author[ $key ] = $user->$key; - } else { - $guest_author[ $key ] = ''; - } - } - // Don't need the old user ID. - unset( $guest_author['ID'] ); - // Retain the user mapping and try to produce a unique user_login based on the name. - $guest_author['linked_account'] = $guest_author['user_login']; - if ( ! empty( $guest_author['display_name'] ) && $guest_author['display_name'] != $guest_author['user_login'] ) { - $guest_author['user_login'] = sanitize_title( $guest_author['display_name'] ); - } elseif ( ! empty( $guest_author['first_name'] ) && ! empty( $guest_author['last_name'] ) ) { - $guest_author['user_login'] = sanitize_title( $guest_author['first_name'] . ' ' . $guest_author['last_name'] ); - } - - $retval = $this->create( $guest_author ); - return $retval; - } - - /** - * Guest authors must have Display Names - * - * @since 3.0 - */ - public function filter_wp_insert_post_empty_content( $maybe_empty, $postarr ) { - - if ( $this->post_type != $postarr['post_type'] ) { - return $maybe_empty; - } - - if ( empty( $postarr['post_title'] ) ) { - return true; - } - - return $maybe_empty; - } - - /** - * On the User Management view, add action links to create or edit - * guest author profiles - * - * @since 3.0 - * - * @param array $actions The existing actions to perform on a user - * @param object $user_object A WP_User object - * @return array $actions Modified actions - */ - public function filter_user_row_actions( $actions, $user_object ) { - - if ( ! current_user_can( $this->list_guest_authors_cap ) || is_network_admin() ) { - return $actions; - } - - $new_actions = array(); - if ( $guest_author = $this->get_guest_author_by( 'linked_account', $user_object->user_login ) ) { - $edit_guest_author_link = get_edit_post_link( $guest_author->ID ); - $new_actions['edit-guest-author'] = '' . __( 'Edit Profile', 'co-authors-plus' ) . ''; - } else { - $query_args = array( - 'action' => 'cap-create-guest-author', - 'user_id' => $user_object->ID, - 'nonce' => wp_create_nonce( 'create-guest-author' ), - ); - $create_guest_author_link = add_query_arg( array_map( 'rawurlencode', $query_args ), admin_url( $this->parent_page ) ); - if ( apply_filters( 'coauthors_show_create_profile_user_link', false ) ) { - $new_actions['create-guest-author'] = '' . __( 'Create Profile', 'co-authors-plus' ) . ''; - } - } - - return $new_actions + $actions; - } - - /** - * Filter 'get_avatar' to replace with our own avatar if one exists - * - * @since 3.0 - */ - public function filter_get_avatar( $avatar, $id_or_email, $size, $default ) { - if ( is_object( $id_or_email ) || ! is_email( $id_or_email ) ) { - return $avatar; - } - - // See if this matches a guest author - $guest_author = $this->get_guest_author_by( 'user_email', $id_or_email ); - if ( ! $guest_author ) { - return $avatar; - } - - $thumbnail = $this->get_guest_author_thumbnail( $guest_author, $size ); - - if ( $thumbnail ) { - return $thumbnail; - } - - return $avatar; - } - - /** - * Filter the URL used in functions like the_author_posts_link() - * - * @since 3.0 - */ - public function filter_author_link( $link, $author_id, $author_nicename ) { - - // If we're using this at the top of the loop on author.php, - // our queried object should be set correctly - if ( ! $author_nicename && is_author() && get_queried_object() ) { - $author_nicename = get_queried_object()->user_nicename; - } - - if ( empty( $link ) ) { - $link = add_query_arg( 'author_name', rawurlencode( $author_nicename ), home_url() ); - } else { - global $wp_rewrite; - $link = $wp_rewrite->get_author_permastruct(); - if ( $link ) { - $link = home_url( user_trailingslashit( str_replace( '%author%', $author_nicename, $link ) ) ); - } else { - $link = add_query_arg( 'author_name', rawurlencode( $author_nicename ), home_url() ); - } - } - return $link; - - } - - /** - * Filter Author Feed Link for non-native authors. - * - * @since 3.1 - * - * @param string $feed_link Required. Original feed link for the author. - * @param string $feed Required. Type of feed being generated. - * @return string Feed link for the author. - */ - public function filter_author_feed_link( $feed_link, $feed ) { - if ( ! is_author() ) { - return $feed_link; - } - - // Get author, then check if author is guest-author because - // that's the only type that will need to be adjusted - $author = get_queried_object(); - if ( $author === null || 'guest-author' != $author->type ) { - return $feed_link; - } - - // The next section is similar to - // get_author_feed_link() in wp-includes/link-template.php - $permalink_structure = get_option( 'permalink_structure' ); - - if ( empty( $feed ) ) { - $feed = get_default_feed(); - } - - if ( '' == $permalink_structure ) { - $link = home_url( "?feed=$feed&author=" . $author->ID ); - } else { - $link = get_author_posts_url( $author->ID ); - $feed_link = ( get_default_feed() === $feed ) ? 'feed' : "feed/$feed"; - $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' ); - } - - return $link; - } - - /** - * Filter Personal Data Exporters to add Guest Author exporter - * - * @since 3.3.1 - */ - public function filter_personal_data_exporter( $exporters ) { - $exporters['cap-guest-author'] = array( - 'exporter_friendly_name' => __( 'Guest Author', 'co-authors-plus' ), - 'callback' => array( $this, 'personal_data_exporter' ), - ); - - return $exporters; - } - - /** - * Finds and exports personal data associated with an email address for guest authors - * - * @since 3.3.1 - * - * @param string $email_address The guest author email address. - * @return array An array of personal data. - */ - public function personal_data_exporter( $email_address ) { - $email_address = trim( $email_address ); - - $data_to_export = array(); - - $author = $this->get_guest_author_by( 'user_email', $email_address ); - - if ( ! $author ) { - return array( - 'data' => array(), - 'done' => true, - ); - } - - $author_data = array( - 'ID' => __( 'ID', 'co-authors-plus' ), - 'user_login' => __( 'Login Name', 'co-authors-plus' ), - 'display_name' => __( 'Display Name', 'co-authors-plus' ), - 'user_email' => __( 'Email', 'co-authors-plus' ), - 'first_name' => __( 'First Name', 'co-authors-plus' ), - 'last_name' => __( 'Last Name', 'co-authors-plus' ), - 'website' => __( 'Website', 'co-authors-plus' ), - 'aim' => __( 'AIM', 'co-authors-plus' ), - 'yahooim' => __( 'Yahoo IM', 'co-authors-plus' ), - 'jabber' => __( 'Jabber / Google Talk', 'co-authors-plus' ), - 'description' => __( 'Biographical Info', 'co-authors-plus' ), - ); - - $author_data_to_export = array(); - - foreach ( $author_data as $key => $name ) { - if ( empty( $author->$key ) ) { - continue; - } - - $author_data_to_export[] = array( - 'name' => $name, - 'value' => $author->$key, - ); - } - - /** - * Filters extra data to allow plugins add data related to guest author - * - * @since 3.3.1 - * - * @param array $extra_data An empty array to be populated with extra data. - * @param int $author->ID The guest author ID - * @param string $email_address The guest author email address - */ - $extra_data = apply_filters( 'coauthors_guest_author_personal_export_extra_data', array(), $author->ID, $email_address ); - - if ( is_array( $extra_data ) && ! empty( $extra_data ) ) { - $author_data_to_export = array_merge( $author_data_to_export, $extra_data ); - } - - $data_to_export[] = array( - 'group_id' => 'cap-guest-author', - 'group_label' => __( 'Guest Author', 'co-authors-plus' ), - 'item_id' => "cap-guest-author-{$author->ID}", - 'data' => $author_data_to_export, - ); - - return array( - 'data' => $data_to_export, - 'done' => true, - ); - } - - /** - * Filters the guest author menu item attributes - * - * @param array $atts { - * The HTML attributes applied to the menu item's `` element, empty strings are ignored. - * - * @type string $title Title attribute. - * @type string $target Target attribute. - * @type string $rel The rel attribute. - * @type string $href The href attribute. - * @type string $aria-current The aria-current attribute. - * } - * @param WP_Post $menu_item The current menu item object. - * @return array - */ - public function filter_nav_menu_attributes( $atts, $menu_item ) { - if ( ! empty( $menu_item->object ) && 'guest-author' === $menu_item->object ) { - $author = $this->get_guest_author_by( 'ID', $menu_item->object_id ); - if ( ! empty( $author->type ) && $author->type === 'guest-author' ) { - $atts['href'] = get_author_posts_url( $author->ID, $author->user_nicename ); - } - } - return $atts; - } -} diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index fb7df6ce..f5025107 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -6,12 +6,10 @@ class CoAuthors_Plus { // Name for the taxonomy we're using to store relationships - // and the post type we're using to store guest authors public $coauthor_taxonomy = 'author'; public $coreauthors_meta_box_name = 'authordiv'; public $coauthors_meta_box_name = 'coauthorsdiv'; - public $force_guest_authors = false; public $_pages_whitelist = array( 'post.php', 'post-new.php', 'edit.php' ); @@ -23,11 +21,6 @@ class CoAuthors_Plus { public $to_be_filtered_caps = array(); - /** - * @var CoAuthors_Guest_Authors - */ - public $guest_authors; - /** * __construct() */ @@ -75,8 +68,9 @@ public function __construct() { add_filter( 'wp_get_object_terms', array( $this, 'filter_wp_get_object_terms' ), 10, 4 ); // Make sure we've correctly set data on guest author pages - add_action( 'posts_selection', array( $this, 'fix_author_page' ) ); // Use posts_selection since it's after WP_Query has built the request, and before it's queried any posts. - add_action( 'the_post', array( $this, 'fix_author_page' ) ); + // TODO LESS. do we need this? + // add_action( 'posts_selection', array( $this, 'fix_author_page' ) ); // Use posts_selection since it's after WP_Query has built the request, and before it's queried any posts. + // add_action( 'the_post', array( $this, 'fix_author_page' ) ); // Support for Edit Flow's calendar and story budget add_filter( 'ef_calendar_item_information_fields', array( $this, 'filter_ef_calendar_item_information_fields' ), 10, 2 ); @@ -88,9 +82,6 @@ public function __construct() { // Filter to send comment moderation notification e-mail to multiple co-authors add_filter( 'comment_moderation_recipients', 'cap_filter_comment_moderation_email_recipients', 10, 2 ); - // Support infinite scroll for Guest Authors on author pages - add_filter( 'infinite_scroll_js_settings', array( $this, 'filter_infinite_scroll_js_settings' ), 10, 2 ); - // Delete Co-Author Cache on Post Save & Post Delete add_action( 'save_post', array( $this, 'clear_cache' ) ); add_action( 'delete_post', array( $this, 'clear_cache' ) ); @@ -99,9 +90,6 @@ public function __construct() { // Filter to correct author on author archive page add_filter( 'get_the_archive_title', array( $this, 'filter_author_archive_title' ) ); - // Filter to display author image if exists instead of avatar - add_filter( 'pre_get_avatar_data', array( $this, 'filter_pre_get_avatar_data_url' ), 10, 2 ); - // Block editor assets for the sidebar plugin. add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_sidebar_plugin_assets' ) ); @@ -118,15 +106,6 @@ public function action_init() { // Allow Co-Authors Plus to be easily translated load_plugin_textdomain( 'co-authors-plus', null, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); - // Load the Guest Authors functionality if needed - if ( $this->is_guest_authors_enabled() ) { - require_once dirname( COAUTHORS_PLUS_FILE ) . '/php/class-coauthors-guest-authors.php'; - $this->guest_authors = new CoAuthors_Guest_Authors(); - if ( apply_filters( 'coauthors_guest_authors_force', false ) ) { - $this->force_guest_authors = true; - } - } - // Maybe automatically apply our template tags if ( apply_filters( 'coauthors_auto_apply_template_tags', false ) ) { global $coauthors_plus_template_filters; @@ -285,20 +264,7 @@ public function supported_post_types() { } /** - * Check whether the guest authors functionality is enabled or not - * Guest authors can be disabled entirely with: - * add_filter( 'coauthors_guest_authors_enabled', '__return_false' ) - * - * @since 3.0 - * - * @return bool - */ - public function is_guest_authors_enabled() { - return apply_filters( 'coauthors_guest_authors_enabled', true ); - } - - /** - * Get a guest author object by a specific type of key + * Get a co-author object by a specific type of key * * @param string $key Key to search by (slug,email) * @param string $value Value to search for @@ -306,14 +272,6 @@ public function is_guest_authors_enabled() { */ public function get_coauthor_by( $key, $value, $force = false ) { - // If Guest Authors are enabled, prioritize those profiles - if ( isset( $this->guest_authors ) && $this->is_guest_authors_enabled() ) { - $guest_author = $this->guest_authors->get_guest_author_by( $key, $value, $force ); - if ( is_object( $guest_author ) ) { - return $guest_author; - } - } - switch ( $key ) { case 'id': case 'login': @@ -340,14 +298,6 @@ public function get_coauthor_by( $key, $value, $force = false ) { return false; } $user->type = 'wpuser'; - // However, if guest authors are enabled and there's a guest author linked to this - // user account, we want to use that instead - if ( isset( $this->guest_authors ) && $this->is_guest_authors_enabled() ) { - $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); - if ( is_object( $guest_author ) ) { - $user = $guest_author; - } - } return $user; } return false; @@ -406,32 +356,7 @@ public function coauthors_meta_box( $post ) { $post_id = $post->ID; $default_user = apply_filters( 'coauthors_default_author', wp_get_current_user() ); - - // @daniel, $post_id and $post->post_author are always set when a new post is created due to auto draft, - // and the else case below was always able to properly assign users based on wp_posts.post_author, - // but that's not possible with force_guest_authors = true. - if ( ! $post_id || ( ! $post->post_author && ! $coauthors_plus->force_guest_authors ) || ( 'post' === $current_screen->base && 'add' === $current_screen->action ) ) { - $coauthors = array(); - // If guest authors is enabled, try to find a guest author attached to this user ID - if ( $this->is_guest_authors_enabled() ) { - $coauthor = $coauthors_plus->guest_authors->get_guest_author_by( 'linked_account', $default_user->user_login ); - if ( $coauthor ) { - $coauthors[] = $coauthor; - } - } - // If the above block was skipped, or if it failed to find a guest author, use the current - // logged-in user, so long as force_guest_authors is false. If force_guest_authors = true, we are - // OK with having an empty authoring box. - if ( ! $coauthors_plus->force_guest_authors && empty( $coauthors ) ) { - if ( is_array( $default_user ) ) { - $coauthors = $default_user; - } else { - $coauthors[] = $default_user; - } - } - } else { - $coauthors = get_coauthors(); - } + $coauthors = get_coauthors(); $count = 0; if ( ! empty( $coauthors ) ) : @@ -768,23 +693,8 @@ public function posts_where_filter( $where, $query ) { if ( $author_term = $this->get_author_term( $coauthor ) ) { $terms[] = $author_term; } - // If this co-author has a linked account, we also need to get posts with those terms - if ( ! empty( $coauthor->linked_account ) ) { - $linked_account = get_user_by( 'login', $coauthor->linked_account ); - if ( $guest_author_term = $this->get_author_term( $linked_account ) ) { - $terms[] = $guest_author_term; - } - } - // Whether to include the original 'post_author' value in the query. - // Don't include it if we're forcing guest authors, or it's obvious our query is for a guest author's posts - if ( $this->force_guest_authors || stripos( $where, '.post_author = 0)' ) ) { - $maybe_both = false; - } else { - $maybe_both = apply_filters( 'coauthors_plus_should_query_post_author', true ); - } - - $maybe_both_query = $maybe_both ? '$1 OR' : ''; + $maybe_both_query = '$1 OR'; if ( ! empty( $terms ) ) { $terms_implode = ''; @@ -805,7 +715,7 @@ public function posts_where_filter( $where, $query ) { $id = '\d+'; } - $maybe_both_query = $maybe_both ? '$0 OR' : ''; + $maybe_both_query = '$0 OR'; // add the taxonomy terms to the where query $where = preg_replace( '/\(?\b(?:' . $wpdb->posts . '\.)?post_author\s*(?:=|IN)\s*\(?\d+\)?\)?/', ' (' . $maybe_both_query . ' ' . $terms_implode . ')', $where, 1 ); @@ -888,16 +798,7 @@ public function coauthors_set_post_author_field( $data, $postarr ) { if ( $author ) { $author_data = $this->get_coauthor_by( 'user_nicename', $author ); - // If it's a guest author and has a linked account, store that information in post_author - // because it'll be the valid user ID - if ( 'guest-author' === $author_data->type && ! empty( $author_data->linked_account ) ) { - $user = get_user_by( 'login', $author_data->linked_account ); - if ( is_object( $user ) ) { - $data['post_author'] = $user->ID; - } - } elseif ( 'wpuser' === $author_data->type ) { - $data['post_author'] = $author_data->ID; - } + $data['post_author'] = $author_data->ID; } } @@ -1058,18 +959,6 @@ public function delete_user_action( $delete_id ) { wp_delete_term( $term->term_id, $this->coauthor_taxonomy ); } - if ( $this->is_guest_authors_enabled() ) { - // Get the deleted user data by user id. - $user_data = get_user_by( 'id', $delete_id ); - - // Get the associated user. - $associated_user = $this->guest_authors->get_guest_author_by( 'linked_account', $user_data->data->user_login ); - - if ( isset( $associated_user->ID ) ) { - // Delete associated guest user. - $this->guest_authors->delete( $associated_user->ID ); - } - } } /** @@ -1221,32 +1110,6 @@ public function fix_author_page( $selection ) { } } - /** - * Filters the Infinite Scroll settings to remove `author` from the query_args - * when we are dealing with a Guest Author - * - * If this isn't removed, the author id can be sent in place of author_name, and the - * normal query interception doesn't work, resulting in incorrect results - * - * @param array $settings The existing IS settings to filter - * @return array The filtered IS settings - */ - public function filter_infinite_scroll_js_settings( $settings ) { - if ( ! is_author() ) { - return $settings; - } - - $author = get_queried_object(); - - if ( $author && 'guest-author' === $author->type ) { - unset( $settings['query_args'][ $this->coauthor_taxonomy ] ); - - $settings['query_args']['author_name'] = $author->user_nicename; - } - - return $settings; - } - /** * Main function that handles search-as-you-type for adding co-authors */ @@ -1271,10 +1134,8 @@ public function ajax_suggest() { } foreach ( $authors as $author ) { - $user_type = 'guest-user'; - if ( $author instanceof WP_User ) { - $user_type = 'wp-user'; - } + + $user_type = 'wp-user'; printf( "%s ∣ %s ∣ %s ∣ %s ∣ %s ∣ %s \n", @@ -1302,26 +1163,28 @@ public function search_authors( $search = '', $ignored_authors = array() ) { // instead of the user details. If the term is missing, we probably need to // back-fill with user details. Let's do this first... easier than running // an upgrade script that could break on a lot of users - $args = array( - 'count_total' => false, - 'search' => sprintf( '*%s*', $search ), - 'search_columns' => array( - 'ID', - 'display_name', - 'user_email', - 'user_login', - ), - 'capability' => array( apply_filters( 'coauthors_edit_author_cap', 'edit_posts' ) ), - 'fields' => 'all_with_meta', - ); - $found_users = get_users( $args ); - foreach ( $found_users as $found_user ) { - $term = $this->get_author_term( $found_user ); - if ( empty( $term ) || empty( $term->description ) ) { - $this->update_author_term( $found_user ); - } - } + // TODO LESS - lets remove this? + // $args = array( + // 'count_total' => false, + // 'search' => sprintf( '*%s*', $search ), + // 'search_columns' => array( + // 'ID', + // 'display_name', + // 'user_email', + // 'user_login', + // ), + // 'capability' => array( apply_filters( 'coauthors_edit_author_cap', 'edit_posts' ) ), + // 'fields' => 'all_with_meta', + // ); + // $found_users = get_users( $args ); + + // foreach ( $found_users as $found_user ) { + // $term = $this->get_author_term( $found_user ); + // if ( empty( $term ) || empty( $term->description ) ) { + // $this->update_author_term( $found_user ); + // } + // } $args = array( 'search' => $search, @@ -1337,7 +1200,7 @@ public function search_authors( $search = '', $ignored_authors = array() ) { return array(); } - // Get the guest author objects + // Get the co-author objects $found_users = array(); foreach ( $found_terms as $found_term ) { $found_user = $this->get_coauthor_by( 'user_nicename', $found_term->slug ); @@ -1514,7 +1377,7 @@ public function get_to_be_filtered_caps() { } /** - * Allows guest authors to edit the post they're co-authors of + * Allows co-authors to edit the post they're co-authors of */ public function filter_user_has_cap( $allcaps, $caps, $args ) { @@ -1785,6 +1648,7 @@ public function clear_cache_on_terms_set( $object_id, $terms, $tt_ids, $taxonomy } /** + * TODO LESS: Do we need this? * Filter of the header of author archive pages to correctly display author. * * @param $title string Archive Page Title @@ -1819,65 +1683,11 @@ public function get_guest_author_post_count( $guest_author ) { $term = $this->get_author_term( $guest_author ); $guest_term = get_term_by( 'slug', 'cap-' . $guest_author->user_nicename, $this->coauthor_taxonomy ); - if ( is_object( $guest_term ) - && ! empty( $guest_author->linked_account ) - && $guest_term->count ) { - $user = get_user_by( 'login', $guest_author->linked_account ); - if ( is_object( $user ) ) { - return count_user_posts( $user->ID ); // phpcs:ignore - } - } elseif ( $term ) { - return $term->count; - } + return $term->count; return 0; } - /** - * Filter to display author image if exists instead of avatar. - * - * @param $url string Avatar URL - * @param $id int Author ID - * - * @return string Avatar URL - */ - public function filter_pre_get_avatar_data_url( $args, $id ) { - global $wp_current_filter; - - if ( isset( $args['url'] ) || ! $id || ! is_numeric( $id ) || ! $this->is_guest_authors_enabled() ) { - return $args; - } - - // Do not filter the icon in the admin bar - if ( doing_filter( 'admin_bar_menu' ) ) { - return $args; - } - - // Do not filter when we have a WordPress user sent from CAP meta box - if ( isset( $args['user_type'] ) && 'wp-user' === $args['user_type'] ) { - return $args; - } - - // Do not filter when on the user screen - $current_screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; - if ( ! is_null( $current_screen ) && isset( $current_screen->parent_base ) && 'users' === $current_screen->parent_base ) { - return $args; - } - - - $coauthor = $this->get_coauthor_by( 'id', $id ); - if ( false !== $coauthor && isset( $coauthor->type ) && 'guest-author' === $coauthor->type ) { - if ( has_post_thumbnail( $id ) ) { - $args['url'] = get_the_post_thumbnail_url( $id, array( $args['width'], $args['height'] ) ); - } elseif ( isset( $coauthor->user_email ) ) { - $args['url'] = get_avatar_url( $coauthor->user_email, $args ); - } else { - $args['url'] = get_avatar_url( '', $args ); // Fallback to default. - } - } - return $args; - } - /** * Conditionally Hide Author Term Description * diff --git a/php/class-coauthors-wp-list-table.php b/php/class-coauthors-wp-list-table.php deleted file mode 100755 index d0f8912e..00000000 --- a/php/class-coauthors-wp-list-table.php +++ /dev/null @@ -1,304 +0,0 @@ -is_search = true; - } - - parent::__construct( - array( - 'plural' => __( 'Co-Authors', 'co-authors-plus' ), - 'singular' => __( 'Co-Author', 'co-authors-plus' ), - ) - ); - } - /** - * Perform Co-Authors Query - */ - public function prepare_items() { - global $coauthors_plus; - - $columns = $this->get_columns(); - $hidden = array(); - $sortable = array( - 'display_name' => array( 'display_name', 'ASC' ), - 'first_name' => array( 'first_name', 'ASC' ), - 'last_name' => array( 'last_name', 'ASC' ), - ); - $_sortable = apply_filters( 'coauthors_guest_author_sortable_columns', $this->get_sortable_columns() ); - - foreach ( (array) $_sortable as $id => $data ) { - if ( empty( $data ) ) { - continue; - } - - $data = (array) $data; - if ( ! isset( $data[1] ) ) { - $data[1] = false; - } - - $sortable[ $id ] = $data; - } - - $this->_column_headers = array( $columns, $hidden, $sortable ); - - $paged = ( isset( $_REQUEST['paged'] ) ) ? (int) $_REQUEST['paged'] : 1; - $per_page = 20; - - $args = array( - 'paged' => $paged, - 'posts_per_page' => $per_page, - 'post_type' => $coauthors_plus->guest_authors->post_type, - 'post_status' => 'any', - 'orderby' => 'title', - 'order' => 'ASC', - ); - - $args = apply_filters( 'coauthors_guest_author_query_args', $args ); - - if ( isset( $_REQUEST['orderby'] ) ) { - switch ( $_REQUEST['orderby'] ) { - case 'display_name': - $args['orderby'] = 'title'; - break; - case 'first_name': - case 'last_name': - $args['orderby'] = 'meta_value'; - $args['meta_key'] = $coauthors_plus->guest_authors->get_post_meta_key( $_REQUEST['orderby'] ); - break; - } - } - if ( isset( $_REQUEST['order'] ) && in_array( strtoupper( $_REQUEST['order'] ), array( 'ASC', 'DESC' ) ) ) { - $args['order'] = strtoupper( $_REQUEST['order'] ); - } - - $this->filters = array( - 'show-all' => __( 'Show all', 'co-authors-plus' ), - 'with-linked-account' => __( 'With linked account', 'co-authors-plus' ), - 'without-linked-account' => __( 'Without linked account', 'co-authors-plus' ), - ); - - if ( isset( $_REQUEST['filter'] ) && array_key_exists( $_REQUEST['filter'], $this->filters ) ) { - $this->active_filter = sanitize_key( $_REQUEST['filter'] ); - } else { - $this->active_filter = 'show-all'; - } - - $key = $coauthors_plus->guest_authors->get_post_meta_key( 'linked_account' ); - switch ( $this->active_filter ) { - case 'with-linked-account': - $args['meta_query'] = array( - array( - 'key' => $key, - 'compare' => '!=', - 'value' => '', - ), - ); - break; - case 'without-linked-account': - $args['meta_query'] = array( - 'relation' => 'OR', - array( - 'key' => $key, - 'compare' => 'NOT EXISTS', - ), - array( - 'key' => $key, - 'compare' => '=', - 'value' => '', - ), - ); - break; - } - - if ( $this->is_search ) { - add_filter( 'posts_where', array( $this, 'filter_query_for_search' ) ); - } - - $author_posts = new WP_Query( $args ); - $items = array(); - foreach ( $author_posts->get_posts() as $author_post ) { - $items[] = $coauthors_plus->guest_authors->get_guest_author_by( 'ID', $author_post->ID ); - } - - if ( $this->is_search ) { - remove_filter( 'posts_where', array( $this, 'filter_query_for_search' ) ); - } - - $this->items = $items; - - $this->set_pagination_args( - array( - 'total_items' => $author_posts->found_posts, - 'per_page' => $per_page, - ) - ); - } - - public function filter_query_for_search( $where ) { - global $wpdb; - if ( isset( $_REQUEST['s'] ) ) { - $var = '%' . sanitize_text_field( $_REQUEST['s'] ) . '%'; - $where .= $wpdb->prepare( ' AND (post_title LIKE %s OR post_name LIKE %s )', $var, $var ); - } - return $where; - } - - /** - * Either there are no co-authors, or the search doesn't match any - */ - public function no_items() { - esc_html_e( 'No matching co-authors were found.', 'co-authors-plus' ); - } - - /** - * Generate the columns of information to be displayed on our list table - */ - public function get_columns() { - $columns = array( - 'display_name' => __( 'Display Name', 'co-authors-plus' ), - 'first_name' => __( 'First Name', 'co-authors-plus' ), - 'last_name' => __( 'Last Name', 'co-authors-plus' ), - 'user_email' => __( 'E-mail', 'co-authors-plus' ), - 'linked_account' => __( 'Linked Account', 'co-authors-plus' ), - 'posts' => __( 'Posts', 'co-authors-plus' ), - ); - - $columns = apply_filters( 'coauthors_guest_author_manage_columns', $columns ); - return $columns; - } - - /** - * Render a single row - */ - public function single_row( $item ) { - static $alternate_class = ''; - $alternate_class = ( '' === $alternate_class ? ' alternate' : '' ); - $row_class = 'guest-author-static' . $alternate_class . '"'; - - echo ''; - $this->single_row_columns( $item ); - echo ''; - } - - /** - * Render columns, some are overridden below - */ - public function column_default( $item, $column_name ) { - - switch ( $column_name ) { - case 'first_name': - case 'last_name': - return $item->$column_name; - case 'user_email': - return '' . esc_html( $item->user_email ) . ''; - - default: - do_action( 'coauthors_guest_author_custom_columns', $column_name, $item->ID ); - break; - } - } - - /** - * Render display name, e.g. author name - */ - public function column_display_name( $item ) { - - $item_edit_link = get_edit_post_link( $item->ID ); - $args = array( - 'action' => 'delete', - 'id' => $item->ID, - '_wpnonce' => wp_create_nonce( 'guest-author-delete' ), - ); - $item_delete_link = add_query_arg( array_map( 'rawurlencode', $args ), menu_page_url( 'view-guest-authors', false ) ); - $item_view_link = get_author_posts_url( $item->ID, $item->user_nicename ); - - $output = coauthors_get_avatar( $item ); - - if ( current_user_can( 'edit_post', $item->ID ) ) { - $output .= '' . esc_html( $item->display_name ) . ''; - } else { - $output .= esc_html( $item->display_name ); - } - - $actions = array(); - if ( current_user_can( 'edit_post', $item->ID ) ) { - $actions['edit'] = '' . __( 'Edit', 'co-authors-plus' ) . ''; - } - if ( current_user_can( 'delete_post', $item->ID ) ) { - $actions['delete'] = '' . __( 'Delete', 'co-authors-plus' ) . ''; - } - $actions['view'] = '' . __( 'View Posts', 'co-authors-plus' ) . ''; - $actions = apply_filters( 'coauthors_guest_author_row_actions', $actions, $item ); - $output .= $this->row_actions( $actions ); - - return $output; - } - - /** - * Render linked account - */ - public function column_linked_account( $item ) { - if ( $item->linked_account ) { - $account = get_user_by( 'login', $item->linked_account ); - if ( $account ) { - if ( current_user_can( 'edit_users' ) ) { - return '' . esc_html( $item->linked_account ) . ''; - } - return $item->linked_account; - } - } - return ''; - } - - /** - * Render the published post count column - */ - public function column_posts( $item ) { - global $coauthors_plus; - $count = $coauthors_plus->get_guest_author_post_count( $item ); - - return '' . $count . ''; - } - - /** - * Allow users to filter the guest authors by various criteria - */ - public function extra_tablenav( $which ) { - - ?>
- filters ) ) { - echo ''; - submit_button( __( 'Filter', 'co-authors-plus' ), 'secondary', false, false ); - } - } - ?> -
- search_box( $coauthors_plus->guest_authors->labels['search_items'], 'guest-authors' ); - parent::display(); - } -} diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index a1fab6aa..9b25a678 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -12,41 +12,6 @@ class CoAuthorsPlus_Command extends WP_CLI_Command { private $args; - /** - * Subcommand to create guest authors based on users - * - * @since 3.0 - * - * @subcommand create-guest-authors - */ - public function create_guest_authors( $args, $assoc_args ) { - global $coauthors_plus; - - $defaults = array( - // There are no arguments at this time - ); - $this->args = wp_parse_args( $assoc_args, $defaults ); - - $users = get_users(); - $created = 0; - $skipped = 0; - $progress = \WP_CLI\Utils\make_progress_bar( 'Processing guest authors...', count( $users ) ); - foreach ( $users as $user ) { - - $result = $coauthors_plus->guest_authors->create_guest_author_from_user_id( $user->ID ); - if ( is_wp_error( $result ) ) { - $skipped++; - } else { - $created++; - } - $progress->tick(); - } - $progress->finish(); - WP_CLI::line( 'All done! Here are your results:' ); - WP_CLI::line( "- {$created} guest author profiles were created" ); - WP_CLI::line( "- {$skipped} users already had guest author profiles" ); - } - /** * Create author terms for all posts that don't have them * @@ -733,205 +698,6 @@ public function remove_terms_from_revisions() { WP_CLI::line( "All done! {$affected} revisions had author terms removed" ); } - /** - * Subcommand to create guest authors from an author list in a WXR file - * - * @subcommand create-guest-authors-from-wxr - * @synopsis --file= - */ - public function create_guest_authors_from_wxr( $args, $assoc_args ) { - global $coauthors_plus; - - $defaults = array( - 'file' => '', - ); - $this->args = wp_parse_args( $assoc_args, $defaults ); - - if ( empty( $this->args['file'] ) || ! is_readable( $this->args['file'] ) ) { - WP_CLI::error( 'Please specify a valid WXR file with the --file arg.' ); - } - - if ( ! class_exists( 'WXR_Parser' ) ) { - require_once WP_CONTENT_DIR . '/plugins/wordpress-importer/parsers.php'; - } - - $parser = new WXR_Parser(); - $import_data = $parser->parse( $this->args['file'] ); - - if ( is_wp_error( $import_data ) ) { - WP_CLI::error( 'Failed to read WXR file.' ); - } - - // Get author nodes - $authors = $import_data['authors']; - - foreach ( $authors as $author ) { - WP_CLI::line( sprintf( 'Processing author %s (%s)', $author['author_login'], $author['author_email'] ) ); - - $guest_author_data = array( - 'display_name' => $author['author_display_name'], - 'user_login' => $author['author_login'], - 'user_email' => $author['author_email'], - 'first_name' => $author['author_first_name'], - 'last_name' => $author['author_last_name'], - 'ID' => $author['author_id'], - ); - - $this->create_guest_author( $guest_author_data ); - } - - WP_CLI::line( 'All done!' ); - } - - /** - * Create a single guest author. - * - * self::create_guest_author() wrapper. - * - * @subcommand create-author - * @synopsis - * [--display_name=] - * [--user_login=] - * [--first_name=] - * [--last_name=] - * [--website=] - * [--user_email=] - * [--description=] - */ - public function create_author( $args, $assoc_args ) { - $this->create_guest_author( $assoc_args ); - } - - /** - * Subcommand to create guest authors from an author list in a CSV file - * - * @subcommand create-guest-authors-from-csv - * @synopsis --file= - */ - public function create_guest_authors_from_csv( $args, $assoc_args ) { - global $coauthors_plus; - - $defaults = array( - 'file' => '', - ); - $this->args = wp_parse_args( $assoc_args, $defaults ); - - if ( empty( $this->args['file'] ) || ! is_readable( $this->args['file'] ) ) { - WP_CLI::error( 'Please specify a valid CSV file with the --file arg.' ); - } - - $file = fopen( $this->args['file'], 'rb' ); - - if ( ! $file ) { - WP_CLI::error( 'Failed to read file.' ); - } - - $authors = array(); - - $row = 0; - while ( false !== ( $data = fgetcsv( $file ) ) ) { - if ( 0 === $row ) { - $field_keys = array_map( 'trim', $data ); - // TODO: bail if required fields not found - } else { - $row_data = array_map( 'trim', $data ); - $author_data = array(); - foreach ( $row_data as $col_num => $val ) { - // Don't use the value of the field key isn't set - if ( empty( $field_keys[ $col_num ] ) ) { - continue; - } - $author_data[ $field_keys[ $col_num ] ] = $val; - } - - $authors[] = $author_data; - } - $row++; - } - fclose( $file ); - - WP_CLI::line( 'Found ' . count( $authors ) . ' authors in CSV' ); - - foreach ( $authors as $author ) { - WP_CLI::line( sprintf( 'Processing author %s (%s)', $author['user_login'], $author['user_email'] ) ); - - $guest_author_data = array( - 'display_name' => sanitize_text_field( $author['display_name'] ), - 'user_login' => sanitize_user( $author['user_login'] ), - 'user_email' => sanitize_email( $author['user_email'] ), - 'website' => esc_url_raw( $author['website'] ), - 'description' => wp_filter_post_kses( $author['description'] ), - 'avatar' => absint( $author['avatar'] ), - ); - - $display_name_space_pos = strpos( $author['display_name'], ' ' ); - - if ( false !== $display_name_space_pos && empty( $author['first_name'] ) && empty( $author['last_name'] ) ) { - $first_name = substr( $author['display_name'], 0, $display_name_space_pos ); - $last_name = substr( $author['display_name'], ( $display_name_space_pos + 1 ) ); - - $guest_author_data['first_name'] = sanitize_text_field( $first_name ); - $guest_author_data['last_name'] = sanitize_text_field( $last_name ); - } elseif ( ! empty( $author['first_name'] ) && ! empty( $author['last_name'] ) ) { - $guest_author_data['first_name'] = sanitize_text_field( $author['first_name'] ); - $guest_author_data['last_name'] = sanitize_text_field( $author['last_name'] ); - } - - $this->create_guest_author( $guest_author_data ); - } - - WP_CLI::line( 'All done!' ); - } - - /** - * Helper function to create a guest author. - * - * @param $author array author args. Required: display_name, user_login - * @return void - */ - private function create_guest_author( $author ) { - global $coauthors_plus; - $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'user_email', $author['user_email'], true ); - - if ( ! $guest_author ) { - $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'user_login', $author['user_login'], true ); - } - - if ( $guest_author ) { - /* translators: Guest Author ID. */ - return WP_CLI::warning( sprintf( esc_html__( '-- Author already exists (ID #%s); skipping.', 'co-authors-plus' ), $guest_author->ID ) ); - } - - WP_CLI::line( esc_html__( '-- Not found; creating profile.', 'co-authors-plus' ) ); - - $guest_author_id = $coauthors_plus->guest_authors->create( - array( - 'display_name' => $author['display_name'], - 'user_login' => $author['user_login'], - 'user_email' => $author['user_email'], - 'first_name' => $author['first_name'], - 'last_name' => $author['last_name'], - 'website' => $author['website'], - 'description' => $author['description'], - 'avatar' => $author['avatar'], - ) - ); - - if ( is_wp_error( $guest_author_id ) ) { - /* translators: The error message. */ - return WP_CLI::warning( sprintf( esc_html__( '-- Failed to create guest author: %s', 'co-authors-plus' ), $guest_author_id->get_error_message() ) ); - } - - if ( isset( $author['author_id'] ) ) { - update_post_meta( $guest_author_id, '_original_author_id', $author['ID'] ); - } - - update_post_meta( $guest_author_id, '_original_author_login', $author['user_login'] ); - - /* translators: Guest Author ID. */ - WP_CLI::success( sprintf( esc_html__( '-- Created as guest author #%s', 'co-authors-plus' ), $guest_author_id ) ); - } - /** * Clear all the caches for memory management. */ diff --git a/template-tags.php b/template-tags.php index 95a41f1a..d874e406 100644 --- a/template-tags.php +++ b/template-tags.php @@ -24,7 +24,7 @@ function get_coauthors( $post_id = 0 ) { $coauthors[] = $post_author; } } - } elseif ( ! $coauthors_plus->force_guest_authors ) { + } else { if ( $post && $post_id == $post->ID ) { $post_author = get_userdata( $post->post_author ); } else { @@ -33,7 +33,7 @@ function get_coauthors( $post_id = 0 ) { if ( ! empty( $post_author ) ) { $coauthors[] = $post_author; } - } // the empty else case is because if we force guest authors, we don't ever care what value wp_posts.post_author has. + } } // remove duplicate $coauthors objects from mapping user accounts to guest authors accounts $coauthors = array_unique( $coauthors, SORT_REGULAR ); @@ -77,8 +77,7 @@ function is_coauthor_for_post( $user, $post_id = 0 ) { } foreach ( $coauthors as $coauthor ) { - if ( ( isset( $coauthor->user_login ) && $user == $coauthor->user_login ) - || ( isset( $coauthor->linked_account ) && $user == $coauthor->linked_account ) ) { + if ( isset( $coauthor->user_login ) && $user == $coauthor->user_login ) { return true; } } @@ -405,16 +404,6 @@ function coauthors_emails( $between = null, $betweenLast = null, $before = null, * @return string */ function coauthors_links_single( $author ) { - if ( 'guest-author' === $author->type && get_the_author_meta( 'website' ) ) { - return sprintf( - '%s', - esc_url( get_the_author_meta( 'website' ) ), - /* translators: Author display name. */ - esc_attr( sprintf( __( 'Visit %s’s website', 'co-authors-plus' ), esc_html( get_the_author() ) ) ), - esc_html( get_the_author() ) - ); - } - if ( get_the_author_meta( 'url' ) ) { return sprintf( '%s', @@ -482,14 +471,6 @@ function get_the_coauthor_meta( $field, $user_id = false ) { foreach ( $coauthors as $coauthor ) { $user_id = $coauthor->ID; - if ( isset( $coauthor->type ) && 'user_url' === $field ) { - if ( 'guest-author' === $coauthor->type ) { - $field = 'website'; - } - } elseif ( 'website' === $field ) { - $field = 'user_url'; - } - if ( isset( $coauthor->$field ) ) { $meta[ $user_id ] = $coauthor->$field; } else { @@ -513,13 +494,10 @@ function the_coauthor_meta( $field, $user_id = 0 ) { * Returns an array of blog users and co-authors. * @param array $args An argument array to customize the returned result. * number (int) (20): The maximum number of (co-)authors to return. - * guest_authors_only (boolean) (false): If true, include only guest authors without WP users. * authors_with_posts_only (boolean) (false): If true, don't query for authors with no posts. * orderby (string) ('name'): A field to order the authors by {@see WP_Term_Query::__construct()} * - * @return array A unique array of WP_User-like objects each containing data for a use or a co-author. - * The returned array may contain a mix of native WP users as well as guest authors as - * designated by $args. You can use the $user->type property to check for the user type. + * @return WP_User[] A unique array WP_User objects each containing data for a user. */ function coauthors_get_users( $args = array() ) { global $coauthors_plus; @@ -551,22 +529,11 @@ function coauthors_get_users( $args = array() ) { } $authors[ $author_term->name ] = $coauthor; + $authors[ $author_term->name ]->post_count = $author_term->count; - // only show guest authors if the $args is set to true - if ( ! $args['guest_authors_only'] || $authors[ $author_term->name ]->type === 'guest-author' ) { - $authors[ $author_term->name ]->post_count = $author_term->count; - } else { - unset( $authors[ $author_term->name ] ); - } } $authors = apply_filters( 'coauthors_wp_list_authors_array', $authors ); - // remove duplicates from linked accounts - $linked_accounts = array_unique( array_column( $authors, 'linked_account' ) ); - foreach ( $linked_accounts as $linked_account ) { - unset( $authors[ $linked_account ] ); - } - return $authors; } @@ -595,7 +562,6 @@ function coauthors_wp_list_authors( $args = array() ) { 'style' => 'list', 'html' => true, 'number' => 20, // A sane limit to start to avoid breaking all the things - 'guest_authors_only' => false, 'authors_with_posts_only' => false, 'orderby' => 'name', ); @@ -719,14 +685,6 @@ function coauthors_get_avatar( $coauthor, $size = 32, $default = '', $alt = fals return ''; } - if ( isset( $coauthor->type ) && 'guest-author' == $coauthor->type ) { - $guest_author_thumbnail = $coauthors_plus->guest_authors->get_guest_author_thumbnail( $coauthor, $size, $class ); - - if ( $guest_author_thumbnail ) { - return $guest_author_thumbnail; - } - } - // Make sure we're dealing with an object for which we can retrieve an email if ( isset( $coauthor->user_email ) ) { return get_avatar( $coauthor->user_email, $size, $default, $alt, array( 'class' => $class ) );