Co-Authors Plus - Version 2.6

Version Description

Download this release

Release Info

Developer danielbachhuber
Plugin Icon wp plugin Co-Authors Plus
Version 2.6
Comparing to
See all releases

Code changes from version 2.5.3 to 2.6

co-authors-plus.php CHANGED
@@ -3,8 +3,8 @@
3
  Plugin Name: Co-Authors Plus
4
  Plugin URI: http://wordpress.org/extend/plugins/co-authors-plus/
5
  Description: Allows multiple authors to be assigned to a post. This plugin is an extended version of the Co-Authors plugin developed by Weston Ruter.
6
- Version: 2.5.3
7
- Author: Mohammad Jangda
8
  Author URI: http://digitalize.ca
9
  Copyright: Some parts (C) 2009-2011, Mohammad Jangda; Other parts (C) 2008, Weston Ruter
10
 
@@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
 
26
  */
27
 
28
- define( 'COAUTHORS_PLUS_VERSION', '2.5.3' );
29
 
30
  if( ! defined( 'COAUTHORS_PLUS_DEBUG' ) )
31
  define( 'COAUTHORS_PLUS_DEBUG', false );
@@ -45,16 +45,12 @@ if( ! defined( 'COAUTHORS_DEFAULT_AFTER' ) )
45
  define( 'COAUTHORS_PLUS_PATH', dirname( __FILE__ ) );
46
  define( 'COAUTHORS_PLUS_URL', plugin_dir_url( __FILE__ ) );
47
 
 
 
48
  class coauthors_plus {
49
 
50
  // Name for the taxonomy we're using to store coauthors
51
  var $coauthor_taxonomy = 'author';
52
- // Unique identified added as a prefix to all options
53
- var $options_group = 'coauthors_plus_';
54
- // Initially stores default option values, but when load_options is run, it is populated with the options stored in the WP db
55
- var $options = array(
56
- 'allow_subscribers_as_authors' => 0,
57
- );
58
 
59
  var $coreauthors_meta_box_name = 'authordiv';
60
  var $coauthors_meta_box_name = 'coauthorsdiv';
@@ -67,16 +63,16 @@ class coauthors_plus {
67
  * __construct()
68
  */
69
  function __construct() {
70
- global $pagenow;
 
 
 
71
 
72
  // Load admin_init function
73
  add_action( 'admin_init', array( $this,'admin_init' ) );
74
 
75
- // Load plugin options
76
- $this->load_options();
77
-
78
  // Register new taxonomy so that we can store all our authors
79
- register_taxonomy( $this->coauthor_taxonomy, 'post', array('hierarchical' => false, 'update_count_callback' => '_update_post_term_count', 'label' => false, 'query_var' => false, 'rewrite' => false, 'sort' => true, 'show_ui' => false ) );
80
 
81
  // Modify SQL queries to include coauthors
82
  add_filter( 'posts_where', array( $this, 'posts_where_filter' ) );
@@ -101,48 +97,46 @@ class coauthors_plus {
101
 
102
  add_filter( 'comment_notification_headers', array( $this, 'notify_coauthors' ), 10, 3 );
103
 
104
- // Add the necessary pages for the plugin
105
- add_action( 'admin_menu', array( $this, 'add_menu_items' ) );
106
-
107
  // Handle the custom author meta box
108
  add_action( 'add_meta_boxes', array( $this, 'add_coauthors_box' ) );
109
  add_action( 'add_meta_boxes', array( $this, 'remove_authors_box' ) );
110
 
111
  // Removes the author dropdown from the post quick edit
112
  add_action( 'load-edit.php', array( $this, 'remove_quick_edit_authors_box' ) );
 
 
 
113
 
114
  // Fix for author info not properly displaying on author pages
115
  add_action( 'the_post', array( $this, 'fix_author_page' ) );
 
116
  }
117
-
118
  function coauthors_plus() {
119
  $this->__construct();
120
- }
121
 
122
  /**
123
  * Initialize the plugin for the admin
124
  */
125
  function admin_init() {
126
  global $pagenow;
127
-
128
- // Register all plugin settings so that we can change them and such
129
- // Not really being used
130
- /*
131
- foreach( $this->options as $option => $value ) {
132
- register_setting( $this->options_group, $this->get_plugin_option_fullname( $option ) );
133
- }
134
- */
135
-
136
  // Hook into load to initialize custom columns
137
  if( $this->is_valid_page() ) {
138
  add_action( 'load-' . $pagenow, array( $this, 'admin_load_page' ) );
139
  }
140
-
141
  // Hooks to add additional coauthors to author column to Edit page
142
  add_filter( 'manage_posts_columns', array( $this, '_filter_manage_posts_columns' ) );
143
  add_filter( 'manage_pages_columns', array( $this, '_filter_manage_posts_columns' ) );
144
  add_action( 'manage_posts_custom_column', array( $this, '_filter_manage_posts_custom_column' ) );
145
  add_action( 'manage_pages_custom_column', array( $this, '_filter_manage_posts_custom_column' ) );
 
 
 
 
 
146
  }
147
 
148
  function admin_load_page() {
@@ -265,7 +259,7 @@ class coauthors_plus {
265
  ?>
266
 
267
  <div id="coauthors-edit" class="hide-if-no-js">
268
- <p><?php _e( 'Click on an author to change them. Click on <strong>Delete</strong> to remove them.', 'co-authors-plus' ); ?></p>
269
  </div>
270
 
271
  <?php wp_nonce_field( 'coauthors-edit', 'coauthors-nonce' ); ?>
@@ -285,14 +279,6 @@ class coauthors_plus {
285
  }
286
  }
287
 
288
- /**
289
- * Adds menu items for the plugin
290
- */
291
- function add_menu_items ( ) {
292
- // Add sub-menu page for Custom statuses
293
- //add_options_page(__( 'Co-Authors Plus', 'co-authors-plus' ), __( 'Co-Authors Plus', 'co-authors-plus' ), 'manage_options', 'co-authors-plus', array( $this, 'settings_page' ) );
294
- }
295
-
296
  /**
297
  * Add coauthors to author column on edit pages
298
  * @param array $post_columns
@@ -323,12 +309,96 @@ class coauthors_plus {
323
  $count = 1;
324
  foreach( $authors as $author ) :
325
  ?>
326
- <a href="edit.php?author=<?php echo $author->ID; ?>"><?php echo $author->display_name ?></a><?php echo ( $count < count( $authors ) ) ? ',' : ''; ?>
327
  <?php
328
  $count++;
329
  endforeach;
330
  }
331
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
  /**
334
  * Modify the author query posts SQL to include posts co-authored
@@ -394,19 +464,21 @@ class coauthors_plus {
394
  // Bail on revisions
395
  if( $data['post_type'] == 'revision' )
396
  return $data;
 
 
397
 
398
- if( isset( $_REQUEST['coauthors-nonce'] ) && is_array( $_POST['coauthors'] ) ) {
399
- $author = $_POST['coauthors'][0];
400
  if( $author ) {
401
  $author_data = get_user_by( 'login', $author );
402
  $data['post_author'] = $author_data->ID;
403
  }
404
- } else {
405
- // If for some reason we don't have the coauthors fields set
406
- if( ! isset( $data['post_author'] ) ) {
407
- $user = wp_get_current_user();
408
- $data['post_author'] = $user->ID;
409
- }
410
  }
411
 
412
  return $data;
@@ -428,7 +500,7 @@ class coauthors_plus {
428
 
429
  if( $this->current_user_can_set_authors() ){
430
  $coauthors = (array) $_POST['coauthors'];
431
- $coauthors = array_map( 'esc_html', $coauthors );
432
  return $this->add_coauthors( $post_id, $coauthors );
433
  }
434
  }
@@ -481,34 +553,62 @@ class coauthors_plus {
481
  // If reassign posts, do that -- use coauthors_update_post
482
  if($reassign_id) {
483
  // Get posts belonging to deleted author
484
- $reassign_user = get_profile_by_id( 'user_login', $reassign_id );
485
  // Set to new author
486
- if( $reassign_user ) {
487
  $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $delete_id ) );
488
 
489
  if ( $post_ids ) {
490
  foreach ( $post_ids as $post_id ) {
491
- $this->add_coauthors( $post_id, array( $reassign_user ), true );
492
  }
493
  }
494
  }
495
  }
496
 
497
- $delete_user = get_profile_by_id( 'user_login', $delete_id );
498
- if( $delete_user ) {
499
  // Delete term
500
- wp_delete_term( $delete_user, $this->coauthor_taxonomy );
501
  }
502
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
 
 
 
 
504
  function filter_count_user_posts( $count, $user_id ) {
505
  $user = get_userdata( $user_id );
506
 
507
  $term = get_term_by( 'slug', $user->user_login, $this->coauthor_taxonomy );
508
 
509
- if( ! $term || is_wp_error( $term ) ) {
510
- $count = 0;
511
- } else {
512
  $count = $term->count;
513
  }
514
 
@@ -558,12 +658,9 @@ class coauthors_plus {
558
  }
559
 
560
  /**
561
- * Main function that handles search-as-you-type
562
  */
563
  function ajax_suggest() {
564
- global $wpdb;
565
-
566
- global $user_level;
567
 
568
  if( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'coauthors-search' ) )
569
  die();
@@ -574,7 +671,7 @@ class coauthors_plus {
574
  if( ! $this->current_user_can_set_authors() )
575
  die();
576
 
577
- $search = esc_html( strtolower( $_REQUEST['q'] ) );
578
 
579
  $authors = $this->search_authors( $search );
580
 
@@ -590,31 +687,37 @@ class coauthors_plus {
590
  die();
591
 
592
  }
593
-
 
 
 
594
  function search_authors( $search = '' ) {
595
- $authors = array();
596
- $author_fields = array( 'ID', 'display_name', 'user_login', 'user_email' );
597
 
598
- if ( function_exists( 'get_users' ) ) {
599
- $search = sprintf( '*%s*', $search ); // Enable wildcard searching
600
- $authors = get_users( array( 'search' => $search, 'who' => 'authors', 'fields' => $author_fields ) );
601
- } else {
602
- // Pre 3.1 support
603
- // This might not be the most eloquent way of doing things, but it's better than a nasty SQL query
604
- $matching_authors = get_editable_authors( get_current_user_id() );
605
-
606
- foreach( $matching_authors as $matching_author ) {
607
- foreach( $author_fields as $author_field ) {
608
- if( isset( $matching_author->$author_field ) && strpos( strtolower( $matching_author->$author_field ), $search ) !== false ) {
609
- $authors[] = $matching_author;
610
- break;
611
- }
612
- }
613
- }
614
- }
615
 
616
  return (array) $authors;
617
  }
 
 
 
 
 
 
 
 
 
618
 
619
  /**
620
  * Functions to add scripts and css
@@ -627,16 +730,18 @@ class coauthors_plus {
627
  // TODO: Check if user can set authors? $this->current_user_can_set_authors()
628
  if( $this->is_valid_page() && $this->authors_supported( $post_type ) ) {
629
 
 
 
630
  wp_enqueue_style( 'co-authors-plus-css', COAUTHORS_PLUS_URL . 'css/co-authors-plus.css', false, COAUTHORS_PLUS_VERSION, 'all' );
631
  wp_enqueue_script( 'co-authors-plus-js', COAUTHORS_PLUS_URL . 'js/co-authors-plus.js', array('jquery', 'suggest'), COAUTHORS_PLUS_VERSION, true);
632
 
633
  $js_strings = array(
634
  'edit_label' => __( 'Edit', 'co-authors-plus' ),
635
- 'delete_label' => __( 'Delete', 'co-authors-plus' ),
636
- 'confirm_delete' => __( 'Are you sure you want to delete this author?', 'co-authors-plus' ),
637
- 'input_box_title' => __( 'Click to change this author', 'co-authors-plus' ),
638
  'search_box_text' => __( 'Search for an author', 'co-authors-plus' ),
639
- 'help_text' => __( 'Click on an author to change them. Click on <strong>Delete</strong> to remove them.', 'co-authors-plus' ),
640
  );
641
  wp_localize_script( 'co-authors-plus-js', 'coAuthorsPlusStrings', $js_strings );
642
 
@@ -762,93 +867,6 @@ class coauthors_plus {
762
  return $message_headers;
763
  }
764
 
765
- /**
766
- * Loads options for the plugin.
767
- * If option doesn't exist in database, it is added
768
- *
769
- * Note: default values are stored in the $this->options array
770
- * Note: a prefix unique to the plugin is appended to all options. Prefix is stored in $this->options_group
771
- */
772
- function load_options ( ) {
773
-
774
- $new_options = array();
775
-
776
- foreach( $this->options as $option => $value ) {
777
- $name = $this->get_plugin_option_fullname( $option );
778
- $return = get_option( $name );
779
- if( $return === false ) {
780
- add_option( $name, $value );
781
- $new_array[$option] = $value;
782
- } else {
783
- $new_array[$option] = $return;
784
- }
785
- }
786
- $this->options = $new_array;
787
-
788
- } // END: load_options
789
-
790
-
791
- /**
792
- * Returns option for the plugin specified by $name, e.g. custom_stati_enabled
793
- *
794
- * Note: The plugin option prefix does not need to be included in $name
795
- *
796
- * @param string name of the option
797
- * @return option|null if not found
798
- *
799
- */
800
- function get_plugin_option ( $name ) {
801
- if( is_array( $this->options ) && $option = $this->options[$name] )
802
- return $option;
803
- else
804
- return null;
805
- } // END: get_option
806
-
807
- // Utility function: appends the option prefix and returns the full name of the option as it is stored in the wp_options db
808
- function get_plugin_option_fullname ( $name ) {
809
- return $this->options_group . $name;
810
- }
811
-
812
- /**
813
- * Adds Settings page for Edit Flow
814
- */
815
- function settings_page( ) {
816
- global $wp_roles;
817
-
818
- ?>
819
- <div class="wrap">
820
- <div class="icon32" id="icon-options-general"><br/></div>
821
- <h2><?php _e('Co-Authors Plus', 'co-authors-plus') ?></h2>
822
-
823
- <form method="post" action="options.php">
824
- <?php settings_fields($this->options_group); ?>
825
-
826
- <table class="form-table">
827
- <tr valign="top">
828
- <th scope="row"><strong><?php _e('Roles', 'co-authors-plus') ?></strong></th>
829
- <td>
830
- <p>
831
- <label for="allow_subscribers_as_authors">
832
- <?php /*<input type="checkbox" name="<?php echo $this->get_plugin_option_fullname('allow_subscribers_as_authors') ?>" value="1" <?php echo ($this->get_plugin_option('allow_subscribers_as_authors')) ? 'checked="checked"' : ''; ?> id="allow_subscribers_as_authors" /> <?php _e('Allow subscribers as authors', 'co-authors-plus') ?>*/ ?>
833
- <input type="checkbox" disabled="disabled" name="<?php echo $this->get_plugin_option_fullname('allow_subscribers_as_authors') ?>" value="1" id="allow_subscribers_as_authors" /> <?php _e('Allow subscribers as authors', 'co-authors-plus') ?>
834
- </label> <br />
835
- <span class="description"><?php _e('Enabling this option will allow you to add users with the subscriber role as authors for posts.', 'co-authors-plus') ?></span>
836
- <br />
837
- <span class="description"><strong>Note:</strong> This option has been removed as of v2.5</span>
838
- </p>
839
- </td>
840
- </tr>
841
-
842
- </table>
843
-
844
- <p class="submit">
845
- <input type="submit" class="button-primary" value="<?php _e('Save Changes', 'co-authors-plus') ?>" />
846
- </p>
847
- </form>
848
- </div>
849
- <?php
850
- }
851
-
852
  function debug($msg, $object) {
853
  if( COAUTHORS_PLUS_DEBUG ) {
854
  echo '<hr />';
@@ -860,51 +878,5 @@ class coauthors_plus {
860
  }
861
  }
862
 
863
- /** Helper Functions **/
864
-
865
- /**
866
- * Replacement for the default WordPress get_profile function, since that doesn't allow for search by user_id
867
- * Returns a the specified column value for the specified user
868
- */
869
- // TODO: Remove this function
870
- if( ! function_exists( 'get_profile_by_id' ) ) {
871
- function get_profile_by_id( $field, $user_id ) {
872
- global $wpdb;
873
-
874
- if( $field && $user_id )
875
- return $wpdb->get_var( $wpdb->prepare( "SELECT $field FROM $wpdb->users WHERE ID = %d", $user_id ) );
876
-
877
- return false;
878
- }
879
- }
880
-
881
- function coauthors_plus_init() {
882
-
883
- $plugin_dir = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
884
- load_plugin_textdomain( 'co-authors-plus', null, $plugin_dir );
885
-
886
- // Check if we're running 3.0
887
- if( function_exists( 'post_type_exists' ) ) {
888
- // Create new instance of the coauthors_plus object
889
- global $coauthors_plus;
890
- $coauthors_plus = new coauthors_plus();
891
-
892
- // Add template tags
893
- require_once('template-tags.php');
894
-
895
- } else {
896
- // TODO: show error
897
-
898
- }
899
- }
900
-
901
- /**
902
- * Function to trigger actions when plugin is activated
903
- */
904
- function coauthors_plus_activate_plugin() {}
905
-
906
- /** Let's get the plugin rolling **/
907
- add_action( 'init', 'coauthors_plus_init' );
908
-
909
- // Hook to perform action when plugin activated
910
- register_activation_hook( __FILE__, 'coauthors_plus_activate_plugin' );
3
  Plugin Name: Co-Authors Plus
4
  Plugin URI: http://wordpress.org/extend/plugins/co-authors-plus/
5
  Description: Allows multiple authors to be assigned to a post. This plugin is an extended version of the Co-Authors plugin developed by Weston Ruter.
6
+ Version: 2.6
7
+ Author: Mohammad Jangda, Daniel Bachhuber
8
  Author URI: http://digitalize.ca
9
  Copyright: Some parts (C) 2009-2011, Mohammad Jangda; Other parts (C) 2008, Weston Ruter
10
 
25
 
26
  */
27
 
28
+ define( 'COAUTHORS_PLUS_VERSION', '2.6' );
29
 
30
  if( ! defined( 'COAUTHORS_PLUS_DEBUG' ) )
31
  define( 'COAUTHORS_PLUS_DEBUG', false );
45
  define( 'COAUTHORS_PLUS_PATH', dirname( __FILE__ ) );
46
  define( 'COAUTHORS_PLUS_URL', plugin_dir_url( __FILE__ ) );
47
 
48
+ require_once( dirname( __FILE__ ) . '/template-tags.php' );
49
+
50
  class coauthors_plus {
51
 
52
  // Name for the taxonomy we're using to store coauthors
53
  var $coauthor_taxonomy = 'author';
 
 
 
 
 
 
54
 
55
  var $coreauthors_meta_box_name = 'authordiv';
56
  var $coauthors_meta_box_name = 'coauthorsdiv';
63
  * __construct()
64
  */
65
  function __construct() {
66
+
67
+ $plugin_dir = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
68
+ load_plugin_textdomain( 'co-authors-plus', null, $plugin_dir );
69
+
70
 
71
  // Load admin_init function
72
  add_action( 'admin_init', array( $this,'admin_init' ) );
73
 
 
 
 
74
  // Register new taxonomy so that we can store all our authors
75
+ register_taxonomy( $this->coauthor_taxonomy, 'post', array('hierarchical' => false, 'update_count_callback' => array( &$this, '_update_users_posts_count' ), 'label' => false, 'query_var' => false, 'rewrite' => false, 'sort' => true, 'show_ui' => false ) );
76
 
77
  // Modify SQL queries to include coauthors
78
  add_filter( 'posts_where', array( $this, 'posts_where_filter' ) );
97
 
98
  add_filter( 'comment_notification_headers', array( $this, 'notify_coauthors' ), 10, 3 );
99
 
 
 
 
100
  // Handle the custom author meta box
101
  add_action( 'add_meta_boxes', array( $this, 'add_coauthors_box' ) );
102
  add_action( 'add_meta_boxes', array( $this, 'remove_authors_box' ) );
103
 
104
  // Removes the author dropdown from the post quick edit
105
  add_action( 'load-edit.php', array( $this, 'remove_quick_edit_authors_box' ) );
106
+
107
+ // Restricts WordPress from blowing away term order on bulk edit
108
+ add_filter( 'wp_get_object_terms', array( &$this, 'filter_wp_get_object_terms' ), 10, 4 );
109
 
110
  // Fix for author info not properly displaying on author pages
111
  add_action( 'the_post', array( $this, 'fix_author_page' ) );
112
+
113
  }
114
+
115
  function coauthors_plus() {
116
  $this->__construct();
117
+ }
118
 
119
  /**
120
  * Initialize the plugin for the admin
121
  */
122
  function admin_init() {
123
  global $pagenow;
124
+
 
 
 
 
 
 
 
 
125
  // Hook into load to initialize custom columns
126
  if( $this->is_valid_page() ) {
127
  add_action( 'load-' . $pagenow, array( $this, 'admin_load_page' ) );
128
  }
129
+
130
  // Hooks to add additional coauthors to author column to Edit page
131
  add_filter( 'manage_posts_columns', array( $this, '_filter_manage_posts_columns' ) );
132
  add_filter( 'manage_pages_columns', array( $this, '_filter_manage_posts_columns' ) );
133
  add_action( 'manage_posts_custom_column', array( $this, '_filter_manage_posts_custom_column' ) );
134
  add_action( 'manage_pages_custom_column', array( $this, '_filter_manage_posts_custom_column' ) );
135
+
136
+ // Hooks to modify the published post number count on the Users WP List Table
137
+ add_filter( 'manage_users_columns', array( $this, '_filter_manage_users_columns' ) );
138
+ add_filter( 'manage_users_custom_column', array( &$this, '_filter_manage_users_custom_column' ), 10, 3 );
139
+
140
  }
141
 
142
  function admin_load_page() {
259
  ?>
260
 
261
  <div id="coauthors-edit" class="hide-if-no-js">
262
+ <p><?php _e( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ); ?></p>
263
  </div>
264
 
265
  <?php wp_nonce_field( 'coauthors-edit', 'coauthors-nonce' ); ?>
279
  }
280
  }
281
 
 
 
 
 
 
 
 
 
282
  /**
283
  * Add coauthors to author column on edit pages
284
  * @param array $post_columns
309
  $count = 1;
310
  foreach( $authors as $author ) :
311
  ?>
312
+ <a href="<?php echo esc_url( get_admin_url( null, 'edit.php?author=' . $author->ID ) ); ?>"><?php echo esc_html( $author->display_name ); ?></a><?php echo ( $count < count( $authors ) ) ? ',' : ''; ?>
313
  <?php
314
  $count++;
315
  endforeach;
316
  }
317
  }
318
+
319
+ /**
320
+ * Unset the post count column because it's going to be inaccurate and provide our own
321
+ */
322
+ function _filter_manage_users_columns( $columns ) {
323
+
324
+ $new_columns = array();
325
+ // Unset and add our column while retaining the order of the columns
326
+ foreach( $columns as $column_name => $column_title ) {
327
+ if ( 'posts' == $column_name )
328
+ $new_columns['coauthors_post_count'] = __( 'Posts', 'co-authors-plus' );
329
+ else
330
+ $new_columns[$column_name] = $column_title;
331
+ }
332
+ return $new_columns;
333
+ }
334
+
335
+ /**
336
+ * Provide an accurate count when looking up the number of published posts for a user
337
+ */
338
+ function _filter_manage_users_custom_column( $value, $column_name, $user_id ) {
339
+ if ( 'coauthors_post_count' != $column_name )
340
+ return $value;
341
+ // We filter count_user_posts() so it provides an accurate number
342
+ $numposts = count_user_posts( $user_id );
343
+ if ( $numposts > 0 ) {
344
+ $value .= "<a href='edit.php?author=$user_id' title='" . esc_attr__( 'View posts by this author' ) . "' class='edit'>";
345
+ $value .= $numposts;
346
+ $value .= '</a>';
347
+ } else {
348
+ $value .= 0;
349
+ }
350
+ return $value;
351
+ }
352
+
353
+ /**
354
+ * When we update the terms at all, we should update the published post count for each author
355
+ */
356
+ function _update_users_posts_count( $terms, $taxonomy ) {
357
+ global $wpdb;
358
+
359
+ $object_types = (array) $taxonomy->object_type;
360
+
361
+ foreach ( $object_types as &$object_type ) {
362
+ list( $object_type ) = explode( ':', $object_type );
363
+ }
364
+
365
+ if ( $object_types )
366
+ $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
367
+
368
+ $object_types = array_unique( $object_types );
369
+
370
+ foreach( (array)$terms as $term_taxonomy_id ) {
371
+ $count = 0;
372
+ if ( 0 == $term_taxonomy_id )
373
+ continue;
374
+ // Get the post IDs for all published posts with this co-author
375
+ $query = $wpdb->prepare( "SELECT $wpdb->posts.ID FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types ) . "') AND term_taxonomy_id = %d", $term_taxonomy_id );
376
+ $all_coauthor_posts = $wpdb->get_results( $query );
377
+
378
+ // Find the term_id from the term_taxonomy_id, and then get the user's user_login from that
379
+ $query = $wpdb->prepare( "SELECT $wpdb->terms.slug FROM $wpdb->term_taxonomy INNER JOIN $wpdb->terms ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->term_taxonomy.term_taxonomy_id = %d", $term_taxonomy_id );
380
+ $term_slug = $wpdb->get_var( $query );
381
+ $author = get_user_by( 'login', $term_slug );
382
+
383
+ // Get all of the post IDs where the user is the primary author
384
+ $query = $wpdb->prepare( "SELECT $wpdb->posts.ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types ) . "') AND post_author = %d;", $author->ID );
385
+ $all_author_posts = $wpdb->get_results( $query );
386
+
387
+ // Dedupe the post IDs and then provide a final count
388
+ $all_posts = array();
389
+ foreach( $all_coauthor_posts as $coauthor_post ) {
390
+ $all_posts[] = $coauthor_post->ID;
391
+ }
392
+ foreach( $all_author_posts as $author_post ) {
393
+ $all_posts[] = $author_post->ID;
394
+ }
395
+ $count = count( array_unique( $all_posts ) );
396
+
397
+ // Save the count to the term's count column
398
+ $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term_taxonomy_id ) );
399
+ }
400
+
401
+ }
402
 
403
  /**
404
  * Modify the author query posts SQL to include posts co-authored
464
  // Bail on revisions
465
  if( $data['post_type'] == 'revision' )
466
  return $data;
467
+
468
+ // @todo this should check the nonce before changing the value
469
 
470
+ if( isset( $_REQUEST['coauthors-nonce'] ) && isset( $_POST['coauthors'] ) && is_array( $_POST['coauthors'] ) ) {
471
+ $author = sanitize_key( $_POST['coauthors'][0] );
472
  if( $author ) {
473
  $author_data = get_user_by( 'login', $author );
474
  $data['post_author'] = $author_data->ID;
475
  }
476
+ }
477
+
478
+ // If for some reason we don't have the coauthors fields set
479
+ if( ! isset( $data['post_author'] ) ) {
480
+ $user = wp_get_current_user();
481
+ $data['post_author'] = $user->ID;
482
  }
483
 
484
  return $data;
500
 
501
  if( $this->current_user_can_set_authors() ){
502
  $coauthors = (array) $_POST['coauthors'];
503
+ $coauthors = array_map( 'sanitize_key', $coauthors );
504
  return $this->add_coauthors( $post_id, $coauthors );
505
  }
506
  }
553
  // If reassign posts, do that -- use coauthors_update_post
554
  if($reassign_id) {
555
  // Get posts belonging to deleted author
556
+ $reassign_user = get_user_by( 'id', $reassign_id );
557
  // Set to new author
558
+ if( is_object( $reassign_user ) ) {
559
  $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $delete_id ) );
560
 
561
  if ( $post_ids ) {
562
  foreach ( $post_ids as $post_id ) {
563
+ $this->add_coauthors( $post_id, array( $reassign_user->user_login ), true );
564
  }
565
  }
566
  }
567
  }
568
 
569
+ $delete_user = get_user_by( 'id', $delete_id );
570
+ if ( is_object( $delete_user ) ) {
571
  // Delete term
572
+ wp_delete_term( $delete_user->user_login, $this->coauthor_taxonomy );
573
  }
574
  }
575
+
576
+ /**
577
+ * Restrict WordPress from blowing away author order when bulk editing terms
578
+ *
579
+ * @since 2.6
580
+ * @props kingkool68, http://wordpress.org/support/topic/plugin-co-authors-plus-making-authors-sortable
581
+ */
582
+ function filter_wp_get_object_terms( $terms, $object_ids, $taxonomies, $args ) {
583
+
584
+ if ( !isset( $_REQUEST['bulk_edit'] ) || $taxonomies != "'author'" )
585
+ return $terms;
586
+
587
+ global $wpdb;
588
+ $orderby = 'ORDER BY tr.term_order';
589
+ $order = 'ASC';
590
+ $object_ids = (int)$object_ids;
591
+ $query = $wpdb->prepare( "SELECT t.slug, t.term_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) $orderby $order" );
592
+ $raw_coauthors = $wpdb->get_results( $query );
593
+ $terms = array();
594
+ foreach( $raw_coauthors as $author ) {
595
+ $terms[] = $author->slug;
596
+ }
597
+
598
+ return $terms;
599
+
600
+ }
601
 
602
+ /**
603
+ * Filter the count_users_posts() core function
604
+ */
605
  function filter_count_user_posts( $count, $user_id ) {
606
  $user = get_userdata( $user_id );
607
 
608
  $term = get_term_by( 'slug', $user->user_login, $this->coauthor_taxonomy );
609
 
610
+ // Only modify the count if the author already exists as a term
611
+ if( $term && !is_wp_error( $term ) ) {
 
612
  $count = $term->count;
613
  }
614
 
658
  }
659
 
660
  /**
661
+ * Main function that handles search-as-you-type for adding authors
662
  */
663
  function ajax_suggest() {
 
 
 
664
 
665
  if( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'coauthors-search' ) )
666
  die();
671
  if( ! $this->current_user_can_set_authors() )
672
  die();
673
 
674
+ $search = sanitize_text_field( strtolower( $_REQUEST['q'] ) );
675
 
676
  $authors = $this->search_authors( $search );
677
 
687
  die();
688
 
689
  }
690
+
691
+ /**
692
+ * Get matching authors based on a search value
693
+ */
694
  function search_authors( $search = '' ) {
 
 
695
 
696
+ $args = array(
697
+ 'search' => sprintf( '*%s*', $search ), // Enable wildcard searching
698
+ 'who' => 'authors',
699
+ 'fields' => array(
700
+ 'ID',
701
+ 'display_name',
702
+ 'user_login',
703
+ 'user_email'
704
+ ),
705
+ );
706
+ add_filter( 'pre_user_query', array( &$this, 'filter_pre_user_query' ) );
707
+ $authors = get_users( $args );
708
+ remove_filter( 'pre_user_query', array( &$this, 'filter_pre_user_query' ) );
 
 
 
 
709
 
710
  return (array) $authors;
711
  }
712
+
713
+ /**
714
+ * Modify get_users() to search display_name instead of user_nicename
715
+ */
716
+ function filter_pre_user_query( &$user_query ) {
717
+ if ( is_object( $user_query ) )
718
+ $user_query->query_where = str_replace( "user_nicename LIKE", "display_name LIKE", $user_query->query_where );
719
+ return $user_query;
720
+ }
721
 
722
  /**
723
  * Functions to add scripts and css
730
  // TODO: Check if user can set authors? $this->current_user_can_set_authors()
731
  if( $this->is_valid_page() && $this->authors_supported( $post_type ) ) {
732
 
733
+ wp_enqueue_script( 'jquery' );
734
+ wp_enqueue_script( 'jquery-ui-sortable' );
735
  wp_enqueue_style( 'co-authors-plus-css', COAUTHORS_PLUS_URL . 'css/co-authors-plus.css', false, COAUTHORS_PLUS_VERSION, 'all' );
736
  wp_enqueue_script( 'co-authors-plus-js', COAUTHORS_PLUS_URL . 'js/co-authors-plus.js', array('jquery', 'suggest'), COAUTHORS_PLUS_VERSION, true);
737
 
738
  $js_strings = array(
739
  'edit_label' => __( 'Edit', 'co-authors-plus' ),
740
+ 'delete_label' => __( 'Remove', 'co-authors-plus' ),
741
+ 'confirm_delete' => __( 'Are you sure you want to remove this author?', 'co-authors-plus' ),
742
+ 'input_box_title' => __( 'Click to change this author, or drag to change their position', 'co-authors-plus' ),
743
  'search_box_text' => __( 'Search for an author', 'co-authors-plus' ),
744
+ 'help_text' => __( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ),
745
  );
746
  wp_localize_script( 'co-authors-plus-js', 'coAuthorsPlusStrings', $js_strings );
747
 
867
  return $message_headers;
868
  }
869
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
870
  function debug($msg, $object) {
871
  if( COAUTHORS_PLUS_DEBUG ) {
872
  echo '<hr />';
878
  }
879
  }
880
 
881
+ global $coauthors_plus;
882
+ $coauthors_plus = new coauthors_plus();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/co-authors-plus.css CHANGED
@@ -27,6 +27,17 @@
27
  background: #EAF2FA;
28
  color:#D54E21;
29
  }
 
 
 
 
 
 
 
 
 
 
 
30
  #coauthors-list .coauthor-gravatar {
31
  float: right;
32
  height: 25px;
27
  background: #EAF2FA;
28
  color:#D54E21;
29
  }
30
+ #coauthors-list .ui-state-highlight {
31
+ border:2px dashed #21759B;
32
+ height:31px;
33
+ margin-top:3px;
34
+ width:200px;
35
+ }
36
+ #coauthors-list .ui-sortable-helper .coauthor-tag {
37
+ cursor: cursor:grabbing;
38
+ cursor:-moz-grabbing;
39
+ cursor:-webkit-grabbing;
40
+ }
41
  #coauthors-list .coauthor-gravatar {
42
  float: right;
43
  height: 25px;
js/co-authors-plus.js CHANGED
@@ -15,6 +15,10 @@ jQuery(document).ready(function () {
15
 
16
  var $coauthor_row = jQuery(elem).closest('.coauthor-row');
17
  $coauthor_row.remove();
 
 
 
 
18
 
19
  return true;
20
  }
@@ -70,11 +74,9 @@ jQuery(document).ready(function () {
70
  var coName = (count == 0) ? 'coauthors-main' : '';
71
  // Add new author to <select>
72
  //coauthors_select_author( author );
73
- var options = {};
74
- } else {
75
- var options = { addDelete: true, addEdit: false };
76
  }
77
-
 
78
  // Create autosuggest box and text tag
79
  if(!co) var co = coauthors_create_autosuggest(author, coName)
80
  var tag = coauthors_create_author_tag(author);
@@ -220,6 +222,9 @@ jQuery(document).ready(function () {
220
  } else {
221
  //coauthors_add_coauthor(login, name, co);
222
  coauthors_add_coauthor(author, $this);
 
 
 
223
  }
224
  }
225
 
@@ -399,6 +404,11 @@ jQuery(document).ready(function () {
399
  coauthors_add_coauthor(this, undefined, true, count );
400
  count++;
401
  });
 
 
 
 
 
402
 
403
  // Create new author-suggest and append it to a new row
404
  var newCO = coauthors_create_autosuggest('', false);
@@ -431,6 +441,17 @@ jQuery(document).ready(function () {
431
  hide_loading();
432
  });
433
 
 
 
 
 
 
 
 
 
 
 
 
434
  });
435
 
436
  if( typeof(console) === 'undefined' ) {
15
 
16
  var $coauthor_row = jQuery(elem).closest('.coauthor-row');
17
  $coauthor_row.remove();
18
+
19
+ // Hide the delete button when there's only one Co-Author
20
+ if ( jQuery( '#coauthors-list .coauthor-row .coauthor-tag' ).length <= 1 )
21
+ jQuery( '#coauthors-list .coauthor-row .coauthors-author-options' ).addClass('hidden');
22
 
23
  return true;
24
  }
74
  var coName = (count == 0) ? 'coauthors-main' : '';
75
  // Add new author to <select>
76
  //coauthors_select_author( author );
 
 
 
77
  }
78
+ var options = { addDelete: true, addEdit: false };
79
+
80
  // Create autosuggest box and text tag
81
  if(!co) var co = coauthors_create_autosuggest(author, coName)
82
  var tag = coauthors_create_author_tag(author);
222
  } else {
223
  //coauthors_add_coauthor(login, name, co);
224
  coauthors_add_coauthor(author, $this);
225
+ // Show the delete button if we now have more than one co-author
226
+ if ( jQuery( '#coauthors-list .coauthor-row .coauthor-tag' ).length > 1 )
227
+ jQuery( '#coauthors-list .coauthor-row .coauthors-author-options' ).removeClass('hidden');
228
  }
229
  }
230
 
404
  coauthors_add_coauthor(this, undefined, true, count );
405
  count++;
406
  });
407
+
408
+ // Hide the delete button if there's only one co-author
409
+ if ( jQuery( '#coauthors-list .coauthor-row .coauthor-tag' ).length < 2 )
410
+ jQuery( '#coauthors-list .coauthor-row .coauthors-author-options' ).addClass('hidden');
411
+
412
 
413
  // Create new author-suggest and append it to a new row
414
  var newCO = coauthors_create_autosuggest('', false);
441
  hide_loading();
442
  });
443
 
444
+ // Make co-authors sortable so an editor can control the order of the authors
445
+ jQuery('#coauthors-edit').ready(function($) {
446
+ $( "#coauthors-list" ).sortable({
447
+ axis: 'y',
448
+ handle: '.coauthor-tag',
449
+ placeholder: 'ui-state-highlight',
450
+ items: 'div.coauthor-row:not(div.coauthor-row:last)',
451
+ containment: 'parent',
452
+ });
453
+ });
454
+
455
  });
456
 
457
  if( typeof(console) === 'undefined' ) {
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === Co-Authors Plus ===
2
  Contributors: batmoo, danielbachhuber
3
  Donate link: http://digitalize.ca/donate
4
- Tags: authors, users, multiple authors, coauthors, multi-author
5
- Tested up to: 3.2.1
6
- Requires at least: 3.0
7
- Stable tag: 2.5.3
8
 
9
- Allows multiple authors to be assigned to a Posts via search-as-you-type input boxes.
10
 
11
  == Description ==
12
 
@@ -20,6 +20,14 @@ The extended version incorporates search-as-you-type functionality for adding us
20
 
21
  == Changelog ==
22
 
 
 
 
 
 
 
 
 
23
  = 2011-08-14 / 2.5.3 =
24
 
25
  * Bug fix: Removed extra comma when only two authors were listed. If you used the COAUTHORS_DEFAULT_BETWEEN_LAST constant, double-check what you have
1
  === Co-Authors Plus ===
2
  Contributors: batmoo, danielbachhuber
3
  Donate link: http://digitalize.ca/donate
4
+ Tags: authors, users, multiple authors, coauthors, multi-author, publishing
5
+ Tested up to: 3.3
6
+ Requires at least: 3.1
7
+ Stable tag: 2.6
8
 
9
+ Allows multiple authors to be assigned to any post type via a search-as-you-type input box
10
 
11
  == Description ==
12
 
20
 
21
  == Changelog ==
22
 
23
+ = 2011-12-22 / 2.6 =
24
+
25
+ * Sortable authors: Drag and drop the order of the authors as you'd like them to appear ([props kingkool68](http://profiles.wordpress.org/users/kingkool68/))
26
+ * Search for authors by display name (instead of nicename which was essentially the same as user_login)
27
+ * Option to remove the first author when there are two or more so it's less confusing
28
+ * Bumped requirements to WordPress 3.1
29
+ * Bug fix: Update the published post count for each user more reliably
30
+
31
  = 2011-08-14 / 2.5.3 =
32
 
33
  * Bug fix: Removed extra comma when only two authors were listed. If you used the COAUTHORS_DEFAULT_BETWEEN_LAST constant, double-check what you have
template-tags.php CHANGED
@@ -16,7 +16,7 @@ function get_coauthors( $post_id = 0, $args = array() ) {
16
 
17
  if(is_array($coauthor_terms) && !empty($coauthor_terms)) {
18
  foreach($coauthor_terms as $coauthor) {
19
- $post_author = get_userdatabylogin($coauthor->name);
20
  // In case the user has been deleted while plugin was deactivated
21
  if(!empty($post_author)) $coauthors[] = $post_author;
22
  }
16
 
17
  if(is_array($coauthor_terms) && !empty($coauthor_terms)) {
18
  foreach($coauthor_terms as $coauthor) {
19
+ $post_author = get_user_by( 'login', $coauthor->name );
20
  // In case the user has been deleted while plugin was deactivated
21
  if(!empty($post_author)) $coauthors[] = $post_author;
22
  }
upgrade.php CHANGED
@@ -27,15 +27,17 @@ function coauthors_plus_upgrade_20 () {
27
  // create new array
28
  $coauthors = array();
29
  // get author id -- try to use get_profile
30
- $coauthors[] = get_profile_by_id('user_login', (int)$single_post->post_author);
 
 
31
  // get coauthors id
32
  $legacy_coauthors = get_post_meta($single_post->ID, '_coauthor');
33
 
34
  if(is_array($legacy_coauthors)) {
35
  //echo '<p>Has Legacy coauthors';
36
  foreach($legacy_coauthors as $legacy_coauthor) {
37
- $legacy_coauthor_login = get_profile_by_id('user_login', (int)$legacy_coauthor);
38
- if($legacy_coauthor_login) $coauthors[] = $legacy_coauthor_login;
39
  }
40
  } else {
41
  // No Legacy coauthors
27
  // create new array
28
  $coauthors = array();
29
  // get author id -- try to use get_profile
30
+ $coauthor = get_user_by( 'id', (int)$single_post->post_author );
31
+ if ( is_object( $coauthor ) )
32
+ $coauthors[] = $coauthor->user_login;
33
  // get coauthors id
34
  $legacy_coauthors = get_post_meta($single_post->ID, '_coauthor');
35
 
36
  if(is_array($legacy_coauthors)) {
37
  //echo '<p>Has Legacy coauthors';
38
  foreach($legacy_coauthors as $legacy_coauthor) {
39
+ $legacy_coauthor_login = get_user_by( 'id', (int)$legacy_coauthor );
40
+ if ( is_object( $legacy_coauthor_login ) ) $coauthors[] = $legacy_coauthor_login->user_login;
41
  }
42
  } else {
43
  // No Legacy coauthors