Co-Authors Plus - Version 2.0

Version Description

Download this release

Release Info

Developer batmoo
Plugin Icon wp plugin Co-Authors Plus
Version 2.0
Comparing to
See all releases

Code changes from version 1.2 to 2.0

Files changed (6) hide show
  1. admin.js +138 -143
  2. co-authors-plus.pot +90 -0
  3. co-authors.php +586 -509
  4. readme.txt +37 -26
  5. suggest.php +0 -74
  6. template-tags.php +351 -0
admin.js CHANGED
@@ -1,4 +1,3 @@
1
- //(function(){
2
  jQuery(document).ready(function () {
3
 
4
  /*
@@ -6,7 +5,8 @@ jQuery(document).ready(function () {
6
  * Iterates through the coauthors-select input box until finds the entry with the associated ID
7
  * @param int User ID
8
  *
9
- */
 
10
  function coauthors_get_author_name( authorID ) {
11
  var select = jQuery('#coauthors-select');
12
 
@@ -25,24 +25,25 @@ jQuery(document).ready(function () {
25
  return false;
26
 
27
  }
 
28
 
29
  /*
30
  * Selects author (specified by authorID) within the appropriate select box (specified by selectID)
31
  * @param int
32
  * @param string ID of the select box
33
  */
34
- function coauthors_select_author( authorID, selectID ) {
35
- if(!selectID) selectID = '#coauthors-select';
36
 
37
  var select = jQuery(selectID);
38
 
39
- if(authorID){
40
  //Find the provided author ID
41
  select.find("option").each(function(i){
42
- if(this.value == authorID) {
43
  jQuery(this).attr('selected','true');
44
- // @TODO: Fix to retain order of selected coauthors
45
- jQuery(this).appendTo(select);
46
  return false;
47
  }
48
  });
@@ -67,22 +68,13 @@ jQuery(document).ready(function () {
67
  }
68
  }
69
 
70
- /*
71
- * Old function not needed; though may be useful for duplicate validation
72
- * @param event
73
- */
74
- var coauthors_select_onchange = function(event){
75
-
76
- };
77
-
78
  /*
79
  * Click handler for the delete button
80
  * @param event
81
  */
82
  var coauthors_delete_onclick = function(event){
83
 
84
- // @TODO: Make i10n friendly
85
- if(confirm('Are you sure you want to delete this author?')) {
86
  var tr = jQuery(this).parent().parent();
87
  var name = tr.find('span.author-tag').text();
88
  coauthors_remove_author(name);
@@ -91,28 +83,19 @@ jQuery(document).ready(function () {
91
  return true;
92
  }
93
  return false;
94
- };
95
-
96
- /*
97
- * Adds a delete button next to an author
98
- * @param object The row to which the new author should be added
99
- */
100
- function coauthors_insert_author_edit_cells(tr){
101
 
102
- // @TODO: Make i10n friendly
103
- var deleteBtn = jQuery('<span></span>')
104
- .addClass('delete-coauthor')
105
- .text('Delete')
106
- .bind('click', coauthors_delete_onclick)
107
- ;
108
 
109
- var td = jQuery('<td></td>')
110
- .addClass('delete')
111
- ;
112
- td.append(deleteBtn);
113
- jQuery(tr).append(td);
114
- return tr;
115
-
116
  }
117
 
118
  /*
@@ -121,20 +104,21 @@ jQuery(document).ready(function () {
121
  * @param string Author Name
122
  * @param object The autosuggest input box
123
  */
124
- function coauthors_save_coauthor(authorID, authorName, co) {
125
 
126
  coauthors_remove_author(co.next().text());
127
 
128
  // get sibling <span>, update, and hide
129
- co.next().html(authorName)
130
- .show()
131
- ;
132
-
 
 
 
133
  // select new author
134
  if(co.attr('name')=='coauthors-main') {
135
- coauthors_select_author( authorID, '#post_author_override' );
136
- } else {
137
- coauthors_select_author( authorID )
138
  }
139
 
140
  }
@@ -147,25 +131,30 @@ jQuery(document).ready(function () {
147
  * @param object The autosuggest input box
148
  * @param boolean Initial set up or not?
149
  */
150
- function coauthors_add_coauthor(authorID, authorName, co, init){
151
- var selectedIndex = -1;
152
 
153
  // Check if editing
154
  if(co && co.next().attr('class')=='author-tag') {
155
- coauthors_save_coauthor(authorID, authorName, co);
156
 
157
  } else {
158
  // Not editing, so we create a new author entry
159
-
 
 
 
 
 
 
 
160
  // Create autosuggest box and text tag
161
- if(!co) var co = coauthors_create_autosuggest(authorName)
162
- var tag = coauthors_create_author_tag(authorName);
163
-
164
- coauthors_add_to_table(co, tag);
165
-
166
- // Add new author to <select>
167
- coauthors_select_author( authorID )
168
-
169
  if(!init) {
170
  // Create new author-suggest and append it to a new row
171
  var newCO = coauthors_create_autosuggest('', false);
@@ -176,7 +165,7 @@ jQuery(document).ready(function () {
176
  co.bind('blur', coauthors_stop_editing);
177
 
178
  // Set the value for the auto-suggest box to the Author's name and hide it
179
- co.val(authorName)
180
  .hide()
181
  .unbind('focus')
182
  ;
@@ -191,20 +180,56 @@ jQuery(document).ready(function () {
191
  * @param object Text tag
192
  * @param
193
  */
194
- function coauthors_add_to_table( co, tag, del ) {
195
  if(co) {
196
- var td = jQuery('<td></td>');
197
- td.className = 'suggest';
198
- td.append(co);
199
- td.append(tag);
 
 
200
  var tr = jQuery('<tr></tr>');
201
  tr.append(td);
202
 
203
  //Add buttons to row
204
- if(tag && !del) coauthors_insert_author_edit_cells(tr);
205
 
206
  jQuery('#coauthors-table').append(tr);
207
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
209
 
210
  /*
@@ -214,7 +239,7 @@ jQuery(document).ready(function () {
214
  */
215
  function coauthors_create_autosuggest(authorName, inputName) {
216
 
217
- if(!inputName) inputName = 'coauthors2[]';
218
 
219
  var co = jQuery('<input/>')
220
  .attr({
@@ -228,15 +253,18 @@ jQuery(document).ready(function () {
228
  function() {
229
 
230
  var vals = this.value.split("|");
231
-
232
- var id = jQuery.trim(vals[0]);
233
- var name = jQuery.trim(vals[1]);
 
 
234
 
235
- if(id=="New") {
236
  //alert('Eventually, this will allow you to add a new author right from here. But it\'s not ready yet. *sigh*');
237
  coauthors_new_author_display(name);
238
  } else {
239
- coauthors_add_coauthor(id, name, co);
 
240
  }
241
  }
242
  })
@@ -247,11 +275,11 @@ jQuery(document).ready(function () {
247
  ;
248
 
249
  if(authorName)
250
- co.attr('value', authorName);
251
  else
252
- co.attr('value', 'Search for an author')
253
  .focus(function(){co.val('')})
254
- .blur(function(){co.val('Search for an author')})
255
  ;
256
 
257
  return co;
@@ -279,28 +307,34 @@ jQuery(document).ready(function () {
279
  * Creates the text tag for an author
280
  * @param string Name of the author
281
  */
282
- function coauthors_create_author_tag (name) {
283
 
284
- // @TODO: need to make i10n friendly
285
  var tag = jQuery('<span></span>')
286
- .html(name)
287
- .attr('title', 'Click to edit')
288
  .addClass('author-tag')
289
  // Add Click event to edit
290
- .click(function(){
291
- var co = tag.prev();
292
-
293
- tag.hide();
294
- co.show()
295
- .focus()
296
- ;
297
-
298
- co.previousAuthor = tag.text();
299
- });
300
-
301
  return tag;
302
  }
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
  /*
306
  * Display form for creating new author
@@ -373,13 +407,14 @@ jQuery(document).ready(function () {
373
  //last_name
374
  //email
375
  //pass1
 
376
  //role
377
  }
378
 
379
 
380
 
381
  if(jQuery('#post_author_override')){
382
-
383
  // Check if user has permissions to change post authors; if not, remove controls and end
384
  if(!coauthors_can_edit_others_posts){
385
  jQuery('#authordiv, #pageauthordiv').remove();
@@ -389,9 +424,9 @@ jQuery(document).ready(function () {
389
  // Changes the meta_box title from "Post Author" to "Post Author(s)"
390
  var h3 = jQuery('#authordiv :header, #pageauthordiv :header').html(
391
  /page[^\/]+$/.test(window.location.href) ?
392
- coauthors_dbx_page_title
393
  :
394
- coauthors_dbx_post_title
395
  );
396
 
397
  // Add the controls to add co-authors
@@ -422,68 +457,28 @@ jQuery(document).ready(function () {
422
  coauthors_table.append(tr);
423
  jQuery(div).append(table);
424
 
425
- // Create input and span for first entry
426
- var nameFirst = select[select.selectedIndex].innerHTML;
427
- var coFirst = coauthors_create_autosuggest(nameFirst, 'coauthors-main')
428
- coFirst.hide();
429
- var tagFirst = coauthors_create_author_tag(nameFirst);
430
- jQuery(select).after(tagFirst)
431
- .after(coFirst)
432
- ;
433
- // Add blur event to suggest box
434
- coFirst.bind('blur', coauthors_stop_editing);
435
-
436
- // Create coauthors select box by cloning it from the drop-down
437
- var coauthors = jQuery('#post_author_override').clone(true)
438
- .attr('id', 'coauthors-select')
439
- .attr('name', 'coauthors[]')
440
- .attr({'multiple':'multiple', 'size':5})
441
- .attr('style','height:10em')
442
- .attr('selectedIndex', '-1')
443
- ;
444
- coauthors.insertAfter('#post_author_override');
445
-
446
- // Hide both select boxes
447
  jQuery('#post_author_override').hide();
448
- coauthors.hide();
449
 
450
- // @TODO: need to make i10n friendly
451
- var help = jQuery('<p></p>').text('Click on an author to edit. Click on "Delete" to remove them.');
452
- jQuery('#authordiv .inside').append(help);
453
-
454
- var presenceInput;
455
- try {
456
- //For MSIE
457
- presenceInput = document.createElement('<input name="coauthors_plugin_is_active" type="hidden" value="1" />');
458
- if(!presenceInput || presenceInput.name != 'coauthors_plugin_is_active')
459
- throw Error();
460
- } catch(e){
461
- presenceInput = document.createElement('input');
462
- presenceInput.name = "coauthors_plugin_is_active";
463
- presenceInput.value = 1;
464
- presenceInput.type = 'hidden';
465
- }
466
- div.appendChild(presenceInput);
467
-
468
  }
469
 
470
  // Select authors already added to the post
471
  var addedAlready = [];
472
- jQuery('#the-list tr').each(function(){
473
- var userID = jQuery(this).find('textarea').val();
474
-
475
- if((jQuery(this).find("input[value='_coauthor']").length) && (!addedAlready[userID])) {
476
- var authorName = coauthors_get_author_name(userID);
477
- if(authorName) coauthors_add_coauthor(userID, authorName, undefined, true );
478
- addedAlready[userID] = true;
479
- }
480
  });
481
 
482
  // Create new author-suggest and append it to a new row
483
  var newCO = coauthors_create_autosuggest('', false);
484
  coauthors_add_to_table(newCO);
485
-
486
  }
487
 
488
  });
489
- //})();
 
1
  jQuery(document).ready(function () {
2
 
3
  /*
5
  * Iterates through the coauthors-select input box until finds the entry with the associated ID
6
  * @param int User ID
7
  *
8
+ */
9
+ /*
10
  function coauthors_get_author_name( authorID ) {
11
  var select = jQuery('#coauthors-select');
12
 
25
  return false;
26
 
27
  }
28
+ */
29
 
30
  /*
31
  * Selects author (specified by authorID) within the appropriate select box (specified by selectID)
32
  * @param int
33
  * @param string ID of the select box
34
  */
35
+ function coauthors_select_author( author, selectID ) {
36
+ if(!selectID) selectID = '#post_author_override';
37
 
38
  var select = jQuery(selectID);
39
 
40
+ if(author.id){
41
  //Find the provided author ID
42
  select.find("option").each(function(i){
43
+ if(this.value == author.id) {
44
  jQuery(this).attr('selected','true');
45
+ // Fix to retain order of selected coauthors
46
+ //jQuery(this).appendTo(select);
47
  return false;
48
  }
49
  });
68
  }
69
  }
70
 
 
 
 
 
 
 
 
 
71
  /*
72
  * Click handler for the delete button
73
  * @param event
74
  */
75
  var coauthors_delete_onclick = function(event){
76
 
77
+ if(confirm(i18n.coauthors.confirm_delete)) {
 
78
  var tr = jQuery(this).parent().parent();
79
  var name = tr.find('span.author-tag').text();
80
  coauthors_remove_author(name);
83
  return true;
84
  }
85
  return false;
86
+ };
87
+
88
+ var coauthors_edit_onclick = function(event) {
89
+ var tag = jQuery(event.currentTarget);
 
 
 
90
 
91
+ var co = tag.prev();
92
+
93
+ tag.hide();
94
+ co.show()
95
+ .focus()
96
+ ;
97
 
98
+ co.previousAuthor = tag.text();
 
 
 
 
 
 
99
  }
100
 
101
  /*
104
  * @param string Author Name
105
  * @param object The autosuggest input box
106
  */
107
+ function coauthors_save_coauthor(author, co) {
108
 
109
  coauthors_remove_author(co.next().text());
110
 
111
  // get sibling <span>, update, and hide
112
+ co.next()
113
+ .html(author.name)
114
+ .show()
115
+ .next()
116
+ .val(author.name)
117
+ ;
118
+
119
  // select new author
120
  if(co.attr('name')=='coauthors-main') {
121
+ coauthors_select_author( author );
 
 
122
  }
123
 
124
  }
131
  * @param object The autosuggest input box
132
  * @param boolean Initial set up or not?
133
  */
134
+ // function coauthors_add_coauthor(authorID, authorName, co, init, count){
135
+ function coauthors_add_coauthor(author, co, init, count){
136
 
137
  // Check if editing
138
  if(co && co.next().attr('class')=='author-tag') {
139
+ coauthors_save_coauthor(author, co);
140
 
141
  } else {
142
  // Not editing, so we create a new author entry
143
+ if(count == 0) {
144
+ var coName = (count == 0) ? 'coauthors-main' : '';
145
+ // Add new author to <select>
146
+ coauthors_select_author( author );
147
+ var options = {};
148
+ } else {
149
+ var options = { addDelete: true, addEdit: false };
150
+ }
151
  // Create autosuggest box and text tag
152
+ if(!co) var co = coauthors_create_autosuggest(author, coName)
153
+ var tag = coauthors_create_author_tag(author);
154
+ var input = coauthors_create_author_hidden_input(author);
155
+
156
+ coauthors_add_to_table(co, tag, input, options);
157
+
 
 
158
  if(!init) {
159
  // Create new author-suggest and append it to a new row
160
  var newCO = coauthors_create_autosuggest('', false);
165
  co.bind('blur', coauthors_stop_editing);
166
 
167
  // Set the value for the auto-suggest box to the Author's name and hide it
168
+ co.val(unescape(author.name))
169
  .hide()
170
  .unbind('focus')
171
  ;
180
  * @param object Text tag
181
  * @param
182
  */
183
+ function coauthors_add_to_table( co, tag, input, options ) {
184
  if(co) {
185
+ var td = jQuery('<td></td>')
186
+ .addClass('suggest')
187
+ .append(co)
188
+ .append(tag)
189
+ .append(input)
190
+ ;
191
  var tr = jQuery('<tr></tr>');
192
  tr.append(td);
193
 
194
  //Add buttons to row
195
+ if(tag) coauthors_insert_author_edit_cells(tr, options);
196
 
197
  jQuery('#coauthors-table').append(tr);
198
  }
199
+ }
200
+
201
+ /*
202
+ * Adds a delete and edit button next to an author
203
+ * @param object The row to which the new author should be added
204
+ */
205
+ function coauthors_insert_author_edit_cells(tr, options){
206
+
207
+ var td = jQuery('<td></td>')
208
+ .addClass('coauthors-author-options')
209
+ ;
210
+
211
+ /*
212
+ if(options.addEdit) {
213
+ var editBtn = jQuery('<span></span>')
214
+ .addClass('edit-coauthor')
215
+ .text(i18n.coauthors.edit_label)
216
+ .bind('click', coauthors_edit_onclick)
217
+ ;
218
+ td.append(editBtn);
219
+ }
220
+ */
221
+ if(options.addDelete) {
222
+ var deleteBtn = jQuery('<span></span>')
223
+ .addClass('delete-coauthor')
224
+ .text(i18n.coauthors.delete_label)
225
+ .bind('click', coauthors_delete_onclick)
226
+ ;
227
+ td.append(deleteBtn);
228
+ }
229
+
230
+ jQuery(tr).append(td);
231
+ return tr;
232
+
233
  }
234
 
235
  /*
239
  */
240
  function coauthors_create_autosuggest(authorName, inputName) {
241
 
242
+ if(!inputName) inputName = 'coauthorsinput[]';
243
 
244
  var co = jQuery('<input/>')
245
  .attr({
253
  function() {
254
 
255
  var vals = this.value.split("|");
256
+
257
+ var author = {}
258
+ author.id = jQuery.trim(vals[0]);
259
+ author.login = jQuery.trim(vals[1]);
260
+ author.name = jQuery.trim(vals[2]);
261
 
262
+ if(author.id=="New") {
263
  //alert('Eventually, this will allow you to add a new author right from here. But it\'s not ready yet. *sigh*');
264
  coauthors_new_author_display(name);
265
  } else {
266
+ //coauthors_add_coauthor(login, name, co);
267
+ coauthors_add_coauthor(author, co);
268
  }
269
  }
270
  })
275
  ;
276
 
277
  if(authorName)
278
+ co.attr('value', unescape(authorName));
279
  else
280
+ co.attr('value', i18n.coauthors.search_box_text)
281
  .focus(function(){co.val('')})
282
+ .blur(function(){co.val(i18n.coauthors.search_box_text)})
283
  ;
284
 
285
  return co;
307
  * Creates the text tag for an author
308
  * @param string Name of the author
309
  */
310
+ function coauthors_create_author_tag (author) {
311
 
 
312
  var tag = jQuery('<span></span>')
313
+ .html(unescape(author.name))
314
+ .attr('title', i18n.coauthors.input_box_title)
315
  .addClass('author-tag')
316
  // Add Click event to edit
317
+ .click(coauthors_edit_onclick);
 
 
 
 
 
 
 
 
 
 
318
  return tag;
319
  }
320
 
321
+ /*
322
+ * Creates the text tag for an author
323
+ * @param string Name of the author
324
+ */
325
+ function coauthors_create_author_hidden_input (author) {
326
+ var input = jQuery('<input />')
327
+ .attr({
328
+ 'type': 'hidden',
329
+ 'id': 'coauthors_hidden_input',
330
+ 'name': 'coauthors[]',
331
+ 'value': unescape(author.login)
332
+ })
333
+ ;
334
+
335
+ return input;
336
+ }
337
+
338
 
339
  /*
340
  * Display form for creating new author
407
  //last_name
408
  //email
409
  //pass1
410
+ //email password checkbox
411
  //role
412
  }
413
 
414
 
415
 
416
  if(jQuery('#post_author_override')){
417
+
418
  // Check if user has permissions to change post authors; if not, remove controls and end
419
  if(!coauthors_can_edit_others_posts){
420
  jQuery('#authordiv, #pageauthordiv').remove();
424
  // Changes the meta_box title from "Post Author" to "Post Author(s)"
425
  var h3 = jQuery('#authordiv :header, #pageauthordiv :header').html(
426
  /page[^\/]+$/.test(window.location.href) ?
427
+ i18n.coauthors.page_metabox_title
428
  :
429
+ i18n.coauthors.post_metabox_title
430
  );
431
 
432
  // Add the controls to add co-authors
457
  coauthors_table.append(tr);
458
  jQuery(div).append(table);
459
 
460
+ // Hide original dropdown box
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  jQuery('#post_author_override').hide();
 
462
 
463
+ // Show help text
464
+ var help = jQuery('<p></p>').text(i18n.coauthors.help_text);
465
+ jQuery('#authordiv .inside').append(help);
466
+ jQuery('#pageauthordiv .inside').append(help);
467
+
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  }
469
 
470
  // Select authors already added to the post
471
  var addedAlready = [];
472
+ //jQuery('#the-list tr').each(function(){
473
+ var count = 0;
474
+ jQuery.each(post_coauthors, function() {
475
+ coauthors_add_coauthor(this, undefined, true, count );
476
+ count++;
 
 
 
477
  });
478
 
479
  // Create new author-suggest and append it to a new row
480
  var newCO = coauthors_create_autosuggest('', false);
481
  coauthors_add_to_table(newCO);
 
482
  }
483
 
484
  });
 
co-authors-plus.pot ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # This file is put in the public domain.
3
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4
+ #
5
+ #, fuzzy
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: PACKAGE VERSION\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/co-authors-plus\n"
10
+ "POT-Creation-Date: 2009-10-11 14:33+0000\n"
11
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=CHARSET\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+
18
+ #: co-authors.php:31
19
+ msgid " and "
20
+ msgstr ""
21
+
22
+ #: co-authors.php:120 co-authors.php:530
23
+ msgid "Co-Authors Plus"
24
+ msgstr ""
25
+
26
+ #: co-authors.php:134
27
+ msgid "Authors"
28
+ msgstr ""
29
+
30
+ #: co-authors.php:378
31
+ msgid "Post Author(s)"
32
+ msgstr ""
33
+
34
+ #: co-authors.php:379
35
+ msgid "Page Author(s)"
36
+ msgstr ""
37
+
38
+ #: co-authors.php:380
39
+ msgid "Edit"
40
+ msgstr ""
41
+
42
+ #: co-authors.php:381
43
+ msgid "Delete"
44
+ msgstr ""
45
+
46
+ #: co-authors.php:382
47
+ msgid "Are you sure you want to delete this author?"
48
+ msgstr ""
49
+
50
+ #: co-authors.php:383
51
+ msgid "Click to change this author"
52
+ msgstr ""
53
+
54
+ #: co-authors.php:384
55
+ msgid "Search for an author"
56
+ msgstr ""
57
+
58
+ #: co-authors.php:385
59
+ msgid ""
60
+ "Click on an author to change them. Click on \\\"Delete\\\" to remove them."
61
+ msgstr ""
62
+
63
+ #: co-authors.php:537
64
+ msgid "Roles"
65
+ msgstr ""
66
+
67
+ #: co-authors.php:541
68
+ msgid "Allow subscribers as authors"
69
+ msgstr ""
70
+
71
+ #: co-authors.php:543
72
+ msgid ""
73
+ "Enabling this option will allow you to add users with the subscriber role as "
74
+ "authors for posts."
75
+ msgstr ""
76
+
77
+ #: co-authors.php:551
78
+ msgid "Save Changes"
79
+ msgstr ""
80
+
81
+ #: template-tags.php:57
82
+ msgid ""
83
+ "No post ID provided for CoAuthorsIterator constructor. Are you not in a loop "
84
+ "or is $post not set?"
85
+ msgstr ""
86
+
87
+ #: template-tags.php:304
88
+ #, php-format
89
+ msgid "Posts by %s"
90
+ msgstr ""
co-authors.php CHANGED
@@ -3,10 +3,10 @@
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. Co-authored posts appear on a co-author's posts page and feed. New template tags allow listing of co-authors. Editors may assign co-authors to a post via the 'Post Author' box. <em>This plugin is an extended version of the Co-Authors plugin originally developed at [Shepherd Interactive](http://www.shepherd-interactive.com/ "Shepherd Interactive specializes in web design and development in Portland, Oregon") (2007). Their plugin was inspired by 'Multiple Authors' plugin by Mark Jaquith (2005).</em>
6
- Version: 1.2
7
  Author: Mohammad Jangda
8
  Author URI: http://digitalize.ca
9
- Copyright: Some parts (C) 2009, Mohammad; Other parts (C) 2008, Weston Ruter, Shepherd Interactive
10
 
11
  GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
12
  This program is free software; you can redistribute it and/or modify
@@ -23,542 +23,619 @@ You should have received a copy of the GNU General Public License
23
  along with this program; if not, write to the Free Software
24
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
 
26
-
27
- ## Change Log ##
28
-
29
- *2009-06-16 / 1.2.0*
30
-
31
- * FIX: Added compatibility for WordPress 2.8
32
- * FIX: Added new template tags (get_the_coauthor_meta & the_coauthor_meta) to fix issues related to displaying author info on author archive pages
33
- * FIX: Plugin should now work for plugins not using the wp_ DB prefix
34
- * FIX: Coauthors should no longer be alphabetically reordered when the post is updated
35
- * UPDATE: Plugin now used WordPress native AJAX calls to tighten security
36
-
37
- *2009-04-26 / 1.1.5*
38
-
39
- * Updated SQL query for autosuggest to search through first name, last name, and nickname
40
- * Added code comments to javascript; more still to be added
41
- * Updated readme information
42
-
43
- *2009-04-25 / 1.1.4*
44
-
45
- * Disabled "New Author" output in suggest box
46
- * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
47
-
48
- *2009-04-23 / 1.1.3*
49
-
50
- * Add blur event to disable input box
51
- * Limit only one edit at a time.
52
- * Check Cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
53
- * Add suggest javascript plugin to Edit Page.
54
-
55
- *2009-04-19 / 1.1.2*
56
-
57
- * Disabled form submit when enter pressed.
58
-
59
- *2009-04-15 / 1.1.1*
60
-
61
- * Changed SQL query to return only contributer-level and above users.
62
-
63
- *2009-04-14: 1.1.0*
64
-
65
- * First beta release
66
-
67
- @@ To do @@
68
- - Setting to enable/disable co-authors for Pages
69
- - admin.js: need to check to ensure that an author added is not a duplicate
70
- - Display all coauthors in table on "Edit Posts" page
71
-
72
  */
73
 
 
74
  define('COAUTHORS_DEFAULT_BEFORE', '');
75
  define('COAUTHORS_DEFAULT_BETWEEN', ', ');
76
- define('COAUTHORS_DEFAULT_BETWEEN_LAST', ' and ');
77
  define('COAUTHORS_DEFAULT_AFTER', '');
78
- define('COAUTHORS_PLUS_VERSION', '1.2');
79
-
80
- if(floatval(get_option('coauthors_plus_version')) < 1.0)
81
- coauthors_updatedb();
82
-
83
- add_option('coauthors_plus_version', COAUTHORS_PLUS_VERSION);
84
-
85
- function coauthors_updatedb(){
86
- global $wpdb;
87
- //Update old versions of plugin to use new hidden meta key
88
- $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_coauthor' WHERE meta_key = 'coauthor';");
89
- }
90
- register_activation_hook(__FILE__, 'coauthors_updatedb');
91
-
92
- # Load up the localization file if we're using WordPress in a different language
93
- # Place l10n files named like "co-authors-[value in wp-config].mo" in the "localization" folder
94
- load_plugin_textdomain('co-authors', PLUGINDIR . '/co-authors-plus/localization');
95
-
96
- function coauthors_user_has_cap($allcaps, $caps, $args){
97
- $current_user = wp_get_current_user();
98
-
99
- $relatedCaps = array(
100
- 'edit_post',
101
- 'edit_others_posts',
102
- 'publish_posts',
103
- 'edit_page',
104
- 'edit_others_pages',
105
- 'publish_pages',
106
- 'edit_pages',
107
- 'edit_posts',
108
- 'edit_published_pages',
109
- 'edit_published_posts',
110
- //delete_post
111
- //delete_page
112
- //moderate_comments
113
- );
114
-
115
- foreach($caps as $cap){
116
- if(!in_array($cap, $relatedCaps))
117
- return $allcaps;
118
- }
119
-
120
- //Get the post in question
121
- $postID = $args[2] ? $args[2] : $_POST['ID'];
122
- $post = get_post($postID);
123
- $post_status = $_POST['post_status'] ? $_POST['post_status'] : $post->post_status;
124
-
125
- //Disallow if post is published and they are a contributor
126
- if(!in_array($post_status, array('draft','pending')) && (($post->post_type == 'post' && !$allcaps['edit_published_posts']) || ($post->post_type == 'page' && !$allcaps['edit_published_pages']))){
127
- return $allcaps;
128
- }
129
-
130
- $coauthors = get_post_custom_values('_coauthor', $postID);
131
- if(!empty($coauthors) && in_array($current_user->ID, $coauthors)){
132
- foreach($relatedCaps as $cap){
133
- $allcaps[$cap] = true;
134
- }
135
- }
136
-
137
- return $allcaps;
138
- }
139
- add_filter('user_has_cap', 'coauthors_user_has_cap', 10, 3);
140
-
141
-
142
- //Modify the author query posts SQL to include posts co-authored
143
- function coauthors_posts_join_filter($join){
144
- global $wpdb,$wp_query;
145
- if(is_author()){
146
- $join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->postmeta.post_id = $wpdb->posts.id "
147
- . "AND $wpdb->postmeta.meta_key = '_coauthor' "
148
- . "AND $wpdb->postmeta.meta_value = '" . $wp_query->query_vars['author'] . "' "; //this condition removes need for DISTINCT
149
- }
150
- return $join;
151
- }
152
- add_filter('posts_join', 'coauthors_posts_join_filter');
153
-
154
- function coauthors_posts_where_filter($where){
155
- global $wpdb;
156
- if(is_author())
157
- $where = preg_replace('/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(\d+))/', '($1 OR (' . $wpdb->postmeta . '.meta_value = \'$2\'))', $where, 1); #' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
158
- return $where;
159
- }
160
- add_filter('posts_where', 'coauthors_posts_where_filter');
161
-
162
- class CoAuthorsIterator {
163
- var $position = -1;
164
- var $original_authordata;
165
- var $authordata_array;
166
- var $count;
167
-
168
- function CoAuthorsIterator($postID = 0){
169
- global $post, $authordata, $wpdb;
170
- $postID = (int)$postID;
171
- if(!$postID && $post)
172
- $postID = (int)$post->ID;
173
- if(!$postID)
174
- trigger_error(__('No post ID provided for CoAuthorsIterator constructor. Are you not in a loop or is $post not set?', 'co-authors')); //return null;
175
- if(empty($authordata))
176
- $authordata = get_userdata($wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $postID;"));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
- //Gather all of the co-authors
179
- $this->authordata_array = array($authordata);
180
- $userids = get_post_meta($post->ID, '_coauthor', false);
181
- if(!empty($userids)){
182
- if(!is_array($userids))
183
- $userids = array($userids);
184
- foreach($userids as $user_id){
185
- $a = get_userdata($user_id);
186
- if(!empty($a)) //in case the user has been deleted while plugin was deactivated
187
- $this->authordata_array[] = $a;
188
- }
189
- }
190
- $this->count = count($this->authordata_array);
191
  }
192
-
193
- function iterate(){
194
- global $authordata;
195
- $this->position++;
196
-
197
- //At the end of the loop
198
- if($this->position > $this->count-1){
199
- $authordata = $this->original_authordata;
200
- $this->position = -1;
201
- return false;
202
- }
203
 
204
- //At the beginning of the loop
205
- if($this->position == 0 && !empty($authordata))
206
- $this->original_authordata = $authordata;
207
-
208
- $authordata = $this->authordata_array[$this->position];
 
 
 
 
 
 
 
 
 
 
209
 
210
- return true;
 
 
 
211
  }
212
 
213
- function get_position(){
214
- if($this->position === -1)
215
- return false;
216
- return $this->position;
217
- }
218
- function is_last(){
219
- return $this->position === $this->count-1;
220
- }
221
- function is_first(){
222
- return $this->position === 0;
223
- }
224
- function count(){
225
- return $this->count;
226
- }
227
- function get_all(){
228
- return $this->authordata_array;
229
- }
230
- }
231
-
232
- //Helper function for the following new template tags
233
- function coauthors__echo($tag, $between, $betweenLast, $before, $after){
234
- $i = new CoAuthorsIterator();
235
- echo $before;
236
- if($i->iterate())
237
- $tag();
238
- while($i->iterate()){
239
- echo $i->is_last() ? $betweenLast : $between;
240
- $tag();
 
 
 
241
  }
242
- echo $after;
243
- }
244
-
245
- //Provide co-author equivalents to the existing author template tags
246
- function coauthors($between = null, $betweenLast = null, $before = null, $after = null){
247
- if($between === NULL)
248
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
249
- if($betweenLast === NULL)
250
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
251
- if($before === NULL)
252
- $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
253
- if($after === NULL)
254
- $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
255
- coauthors__echo('the_author', $between, $betweenLast, $before, $after);
256
- }
257
- function coauthors_posts_links($between = null, $betweenLast = null, $before = null, $after = null){
258
- if($between === NULL)
259
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
260
- if($betweenLast === NULL)
261
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
262
- if($before === NULL)
263
- $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
264
- if($after === NULL)
265
- $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
266
- coauthors__echo('the_author_posts_link', $between, $betweenLast, $before, $after);
267
- }
268
- function coauthors_firstnames($between = null, $betweenLast = null, $before = null, $after = null){
269
- if($between === NULL)
270
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
271
- if($betweenLast === NULL)
272
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
273
- if($before === NULL)
274
- $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
275
- if($after === NULL)
276
- $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
277
- coauthors__echo('the_author_firstname', $between, $betweenLast, $before, $after);
278
- }
279
- function coauthors_lastnames($between = null, $betweenLast = null, $before = null, $after = null){
280
- if($between === NULL)
281
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
282
- if($betweenLast === NULL)
283
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
284
- if($before === NULL)
285
- $before = COAUTHORS_DEFAULT_BEFORE;
286
- if($after === NULL)
287
- $after = COAUTHORS_DEFAULT_AFTER;
288
- coauthors__echo('the_author_lastname', $between, $betweenLast, $before, $after);
289
- }
290
- function coauthors_nicknames($between = null, $betweenLast = null, $before = null, $after = null){
291
- if($between === NULL)
292
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
293
- if($betweenLast === NULL)
294
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
295
- if($before === NULL)
296
- $before = COAUTHORS_DEFAULT_BEFORE;
297
- if($after === NULL)
298
- $after = COAUTHORS_DEFAULT_AFTER;
299
- coauthors__echo('the_author_nickname', $between, $betweenLast, $before, $after);
300
- }
301
- function coauthors_links($between = null, $betweenLast = null, $before = null, $after = null){
302
- if($between === NULL)
303
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
304
- if($betweenLast === NULL)
305
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
306
- if($before === NULL)
307
- $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
308
- if($after === NULL)
309
- $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
310
- coauthors__echo('the_author_link', $between, $betweenLast, $before, $after);
311
- }
312
- function coauthors_IDs($between = null, $betweenLast = null, $before = null, $after = null){
313
- if($between === NULL)
314
- $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
315
- if($betweenLast === NULL)
316
- $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
317
- if($before === NULL)
318
- $before = COAUTHORS_DEFAULT_BEFORE;
319
- if($after === NULL)
320
- $after = COAUTHORS_DEFAULT_AFTER;
321
- coauthors__echo('the_author_ID', $between, $betweenLast, $before, $after);
322
- }
323
 
324
- function get_the_coauthor_meta( $field, $userID = 0 ) {
325
- if(is_author() && $userID == 0) {
326
- global $wp_query;
327
- $curauth = $wp_query->get_queried_object();
 
 
 
 
 
 
 
328
 
329
- if(function_exists('get_the_author_meta')) {//get_bloginfo('version') >= 2.8) {
330
- return get_the_author_meta('description', $curauth->ID);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  }
 
 
332
  }
333
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- function the_coauthor_meta( $field, $userID = 0 ) {
336
- echo get_the_coauthor_meta($field, $userID);
337
- }
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
- /*
340
- * Init the plugin
341
- */
342
- function coauthors_init(){
343
- if(is_admin()) {
344
 
345
- }
346
- }
347
- add_action('init', 'coauthors_init');
348
-
349
- // Add the main JS script and CSS file
350
- if(get_bloginfo('version') >= 2.8) {
351
- // Using WordPress 2.8, are we?
352
- add_action('admin_enqueue_scripts', 'coauthors_enqueue_scripts');
353
- function coauthors_enqueue_scripts($hook_suffix) {
354
- wp_enqueue_style('co-authors-plus', plugins_url('co-authors-plus/admin.css'), false, '', 'all');
355
- wp_enqueue_script('co-authors-plus', plugins_url('co-authors-plus/admin.js'), array('jquery', 'suggest', 'sack'), '', true);
 
 
 
 
 
 
 
 
356
  }
357
- } else {
358
- // Pfft, you're old school
359
- add_action('admin_print_scripts', 'coauthors_enqueue_scripts_pre28');
360
- function coauthors_enqueue_scripts_pre28($hook_suffix) {
361
- //wp_enqueue_style('co-authors-plus', plugins_url('co-authors-plus/admin.css'), false, '', 'all');
362
- wp_enqueue_script('co-authors-plus', plugins_url('co-authors-plus/admin.js'), array('jquery', 'suggest', 'sack'), '');
 
363
  ?>
364
- <link type="text/css" rel="stylesheet" href="<?php echo plugins_url('co-authors-plus/admin.css') ?>" media="all" />
365
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
 
368
  }
369
 
370
- // Add JS variables
371
- add_action('admin_print_scripts', 'coauthors_admin_header' );
372
- function coauthors_admin_header() {
373
- global $current_user;
374
 
375
- wp_print_scripts( array( 'sack' ));
376
-
377
- ?>
378
- <script type="text/javascript">
379
- //<![CDATA[
380
 
381
- // Not currently used, but likely will when the 'Create New Author' functionality is built
382
- var coauthors_sack = new sack("<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php" );
383
-
384
- // The link used for the autosuggest
385
- var coauthor_ajax_suggest_link = "<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php?action=coauthors_ajax_suggest"
386
-
387
- var coauthors_can_edit_others_posts = "<?php echo ($current_user->has_cap('edit_others_posts') ? 'true' : 'false')?>";
388
- var coauthors_dbx_post_title = "<?php _e('Post Author(s)', 'co-authors')?>";
389
- var coauthors_dbx_page_title = "<?php _e('Page Author(s)', 'co-authors')?>";
390
- var coauthors_add_author_label = "<?php _e('+ Add author', 'co-authors')?>";
391
- var coauthors_confirm_delete_label = "<?php _e('Are you sure you want to remove the user \u201C%s\u201D as an author?', 'co-authors')?>";
392
-
393
- //]]>
394
- </script>
395
- <?php
396
- } // end of PHP function coauthor_js_admin_header
397
-
398
- // Update a post's co-authors
399
- function coauthors_update_post($postID){
400
- global $current_user, $wpdb;
401
- if($current_user->has_cap('edit_others_posts') && @$_POST['coauthors_plugin_is_active']){
402
- //Delete all existing co-authors from a post
403
- delete_post_meta($postID, '_coauthor');
404
-
405
- //Newly add each co-author to the post meta
406
- if(is_array($_POST['coauthors'])){
407
- foreach(array_unique($_POST['coauthors']) as $authorID){
408
- if(is_numeric($authorID) && $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE ID = $authorID")){
409
- add_post_meta($postID, '_coauthor', (int)$authorID, false);
410
- }
411
- }
412
- }
413
- }
414
- }
415
- add_action('edit_post', 'coauthors_update_post');
416
- add_action('save_post', 'coauthors_update_post');
417
-
418
- function coauthors_delete_user_action($userID){
419
- global $wpdb;
420
- $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_key = '_coauthor' AND meta_value = '$userID';");
421
- }
422
- add_action('delete_user', 'coauthors_delete_user_action');
423
-
424
-
425
- //customized wp_list_authors() from WP core
426
- /**
427
- * List all the *co-authors* of the blog, with several options available.
428
- * optioncount (boolean) (false): Show the count in parenthesis next to the author's name.
429
- * exclude_admin (boolean) (true): Exclude the 'admin' user that is installed by default.
430
- * show_fullname (boolean) (false): Show their full names.
431
- * hide_empty (boolean) (true): Don't show authors without any posts.
432
- * feed (string) (''): If isn't empty, show links to author's feeds.
433
- * feed_image (string) (''): If isn't empty, use this image to link to feeds.
434
- * echo (boolean) (true): Set to false to return the output, instead of echoing.
435
- * @param array $args The argument array.
436
- * @return null|string The output, if echo is set to false.
437
- */
438
- function coauthors_wp_list_authors($args = ''){
439
- global $wpdb;
440
-
441
- $defaults = array(
442
- 'optioncount' => false, 'exclude_admin' => true,
443
- 'show_fullname' => false, 'hide_empty' => true,
444
- 'feed' => '', 'feed_image' => '', 'echo' => true
445
- );
446
-
447
- $r = wp_parse_args( $args, $defaults );
448
- extract($r, EXTR_SKIP);
449
-
450
- $return = '';
451
-
452
- // TODO: Move select to get_authors().
453
- $authors = $wpdb->get_results("SELECT ID, user_nicename from $wpdb->users " . ($exclude_admin ? "WHERE user_login <> 'admin' " : '') . "ORDER BY display_name");
454
-
455
- $author_count = array();
456
- $sql = "SELECT DISTINCT
457
- p1.post_author,
458
- (COUNT(ID)+(SELECT COUNT(*)
459
- FROM $wpdb->posts p2, $wpdb->postmeta pm
460
- WHERE p2.ID = pm.post_id
461
- AND pm.meta_key = '_coauthor'
462
- AND pm.meta_value = p1.post_author)
463
- ) AS count
464
- FROM $wpdb->posts p1
465
- WHERE post_type = 'post' AND " . get_private_posts_cap_sql( 'post' ) . "
466
- GROUP BY post_author";
467
-
468
- foreach ((array) $wpdb->get_results($sql) as $row) {
469
- $author_count[$row->post_author] = $row->count;
470
- }
471
-
472
- foreach ( (array) $authors as $author ) {
473
- $author = get_userdata( $author->ID );
474
- $posts = (isset($author_count[$author->ID])) ? $author_count[$author->ID] : 0;
475
- $name = $author->display_name;
476
-
477
- if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
478
- $name = "$author->first_name $author->last_name";
479
-
480
- if ( !($posts == 0 && $hide_empty) )
481
- $return .= '<li>';
482
- if ( $posts == 0 ) {
483
- if ( !$hide_empty )
484
- $link = $name;
485
- } else {
486
- $link = '<a href="' . get_author_posts_url($author->ID, $author->user_nicename) . '" title="' . sprintf(__("Posts by %s"), attribute_escape($author->display_name)) . '">' . $name . '</a>';
487
-
488
- if ( (! empty($feed_image)) || (! empty($feed)) ) {
489
- $link .= ' ';
490
- if (empty($feed_image))
491
- $link .= '(';
492
- $link .= '<a href="' . get_author_rss_link(0, $author->ID, $author->user_nicename) . '"';
493
-
494
- if ( !empty($feed) ) {
495
- $title = ' title="' . $feed . '"';
496
- $alt = ' alt="' . $feed . '"';
497
- $name = $feed;
498
- $link .= $title;
499
- }
500
-
501
- $link .= '>';
502
-
503
- if ( !empty($feed_image) )
504
- $link .= "<img src=\"$feed_image\" border=\"0\"$alt$title" . ' />';
505
- else
506
- $link .= $name;
507
-
508
- $link .= '</a>';
509
-
510
- if ( empty($feed_image) )
511
- $link .= ')';
512
- }
513
-
514
- if ( $optioncount )
515
- $link .= ' ('. $posts . ')';
516
-
517
- }
518
-
519
- if ( !($posts == 0 && $hide_empty) )
520
- $return .= $link . '</li>';
521
- }
522
- if ( !$echo )
523
- return $return;
524
- echo $return;
525
  }
526
 
527
- add_action('wp_ajax_coauthors_ajax_suggest', 'coauthors_ajax_suggest' );
528
- function coauthors_ajax_suggest() {
529
- global $wpdb;
530
-
531
- // Make sure that user is logged in; we don't want to enable direct access
532
- get_currentuserinfo();
533
- global $user_level;
534
- if ($user_level >= 7) {
535
-
536
- $q = '%'.strtolower($_REQUEST["q"]).'%';
537
- if (!$q) return;
538
 
539
- $authors_query = $wpdb->prepare("SELECT DISTINCT u.ID, u.display_name, u.user_email FROM $wpdb->users AS u"
540
- ." INNER JOIN $wpdb->usermeta AS um ON u.ID = um.user_id"
541
- ." WHERE ID = ANY (SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '".$wpdb->prefix."user_level' AND meta_value >= 1)"
542
- ." AND (um.meta_key = 'first_name' OR um.meta_key = 'last_name' OR um.meta_key = 'nickname')"
543
- ." AND (u.user_login LIKE %s"
544
- ." OR u.user_nicename LIKE %s"
545
- ." OR u.display_name LIKE %s"
546
- ." OR u.user_email LIKE %s"
547
- ." OR um.meta_value LIKE %s)",$q,$q,$q,$q,$q);
548
-
549
-
550
- $authors = $wpdb->get_results($authors_query, ARRAY_A);
551
-
552
- if(is_array($authors)) {
553
- foreach ($authors as $author) {
554
-
555
- echo $author['ID']." | ". $author['display_name'] ." | ".$author['user_email'] ."\n";
556
- }
557
- }
558
- //echo "New | Add new author: ".trim($q,'%')."\n";
559
- }
560
- die();
561
-
562
- }
563
 
 
 
564
  ?>
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. Co-authored posts appear on a co-author's posts page and feed. New template tags allow listing of co-authors. Editors may assign co-authors to a post via the 'Post Author' box. <em>This plugin is an extended version of the Co-Authors plugin originally developed at [Shepherd Interactive](http://www.shepherd-interactive.com/ "Shepherd Interactive specializes in web design and development in Portland, Oregon") (2007). Their plugin was inspired by 'Multiple Authors' plugin by Mark Jaquith (2005).</em>
6
+ Version: 2.0
7
  Author: Mohammad Jangda
8
  Author URI: http://digitalize.ca
9
+ Copyright: Some parts (C) 2009, Mohammad Jangda; Other parts (C) 2008, Weston Ruter, Shepherd Interactive
10
 
11
  GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
12
  This program is free software; you can redistribute it and/or modify
23
  along with this program; if not, write to the Free Software
24
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  */
27
 
28
+ define('COAUTHORS_FILE_PATH', '');
29
  define('COAUTHORS_DEFAULT_BEFORE', '');
30
  define('COAUTHORS_DEFAULT_BETWEEN', ', ');
31
+ define('COAUTHORS_DEFAULT_BETWEEN_LAST', __(' and '));
32
  define('COAUTHORS_DEFAULT_AFTER', '');
33
+ define('COAUTHORS_PLUS_VERSION', '2.0');
34
+
35
+ require_once('template-tags.php');
36
+
37
+ class coauthors_plus {
38
+
39
+ // Name for the taxonomy we're using to store coauthors
40
+ var $coauthor_taxonomy = 'author';
41
+ // Unique identified added as a prefix to all options
42
+ var $options_group = 'coauthors_plus_';
43
+ // Initially stores default option values, but when load_options is run, it is populated with the options stored in the WP db
44
+ var $options = array(
45
+ 'allow_subscribers_as_authors' => 0,
46
+ );
47
+
48
+ function __construct() {
49
+ global $pagenow;
50
+
51
+ // Load plugin options
52
+ $this->load_options();
53
+
54
+ // Register new taxonomy so that we can store all our authors
55
+ if(!is_taxonomy($this->coauthor_taxonomy)) 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 ) );
56
+
57
+ // Modify SQL queries to include coauthors
58
+ add_filter('posts_where', array(&$this, 'posts_where_filter'));
59
+ add_filter('posts_join', array(&$this, 'posts_join_filter'));
60
+ add_filter('posts_groupby', array(&$this, 'posts_groupby_filter'));
61
+
62
+ // Hooks to add additional coauthors to author column to Edit Posts page
63
+ if($pagenow == 'edit.php') {
64
+ add_filter('manage_posts_columns', array(&$this, '_filter_manage_posts_columns'));
65
+ add_action('manage_posts_custom_column', array(&$this, '_filter_manage_posts_custom_column'));
66
+ }
67
+
68
+ // Action to set users when a post is saved
69
+ //add_action('edit_post', array(&$this, 'coauthors_update_post'));
70
+ add_action('save_post', array(&$this, 'coauthors_update_post'));
71
+
72
+ // Action to reassign posts when a user is deleted
73
+ add_action('delete_user', array(&$this, 'delete_user_action'));
74
+
75
+ // Action to set up author auto-suggest
76
+ add_action('wp_ajax_coauthors_ajax_suggest', array(&$this, 'ajax_suggest') );
77
+
78
+ // Filter to allow coauthors to edit posts
79
+ add_filter('user_has_cap', array(&$this, 'add_coauthor_cap'), 10, 3 );
80
+
81
+ add_filter('comment_notification_headers', array(&$this, 'notify_coauthors'), 10, 3);
82
+
83
+ // Add the main JS script and CSS file
84
+ if(get_bloginfo('version') >= 2.8) {
85
+ // Using WordPress 2.8, are we?
86
+ add_action('admin_enqueue_scripts', array(&$this, 'enqueue_scripts'));
87
+ } else {
88
+ // Pfft, you're old school
89
+ add_action('admin_print_scripts', array(&$this, 'enqueue_scripts_legacy'));
90
+ }
91
+ // Add necessary JS variables
92
+ add_action('admin_print_scripts', array(&$this, 'js_vars') );
93
+
94
+ }
95
+
96
+ function init() {
97
+ //Add the necessary pages for the plugin
98
+ add_action('admin_menu', array(&$this, 'add_menu_items'));
99
+ }
100
+
101
+ /**
102
+ * Initialize the plugin for the admin
103
+ */
104
+ function admin_init() {
105
+ // Register all plugin settings so that we can change them and such
106
+ foreach($this->options as $option => $value) {
107
+ register_setting($this->options_group, $this->get_plugin_option_fullname($option));
108
+ }
109
+ }
110
+ /**
111
+ * Function to trigger actions when plugin is activated
112
+ */
113
+ function activate_plugin() {}
114
+
115
+ /**
116
+ * Adds menu items for the plugin
117
+ */
118
+ function add_menu_items ( ) {
119
+ // Add sub-menu page for Custom statuses
120
+ add_options_page(__('Co-Authors Plus'), __('Co-Authors Plus'), 8, __FILE__, array(&$this, 'settings_page'));
121
+ }
122
+
123
+ /**
124
+ * Add coauthors to author column on edit pages
125
+ *
126
+ * @param array $post_columns
127
+ **/
128
+ function _filter_manage_posts_columns($posts_columns) {
129
+ $new_columns = array();
130
+ foreach ($posts_columns as $key => $value) {
131
+ $new_columns[$key] = $value;
132
+ if ($key == 'author') {
133
+ unset($new_columns[$key]);
134
+ $new_columns['coauthors'] = __('Authors');
135
+ }
136
+ }
137
+ return $new_columns;
138
+ } // END: _filter_manage_posts_columns
139
+
140
+ /**
141
+ * Insert coauthors into post rows on Edit Page
142
+ *
143
+ * @param string $column_name
144
+ **/
145
+ function _filter_manage_posts_custom_column($column_name) {
146
+ if ($column_name == 'coauthors') {
147
+ global $post;
148
+ $authors = get_coauthors($post->ID);
149
+
150
+ $count = 1;
151
+ foreach($authors as $author) :
152
+ ?>
153
+ <a href="edit.php?author=<?php echo $author->ID; ?>"><?php echo $author->display_name ?></a><?php echo ($count < count($authors)) ? ',' : ''; ?>
154
+ <?php
155
+ $count++;
156
+ endforeach;
157
+ }
158
+ }
159
+
160
+ /* Modify the author query posts SQL to include posts co-authored
161
+ *
162
+ */
163
+ function posts_join_filter($join){
164
+ global $wpdb,$wp_query;
165
+
166
+ if(is_author()){
167
+ $join .= " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
168
+ }
169
+ return $join;
170
+ }
171
+ /* Modify
172
+ *
173
+ */
174
+ function posts_where_filter($where){
175
+ global $wpdb, $wp_query;
176
 
177
+ if(is_author()) {
178
+ $author = get_userdata($wp_query->query_vars['author']);//get_profile( 'user_login', $wp_query->query_vars['author']);
179
+ $term = get_term_by('name', $author->user_login, $this->coauthor_taxonomy);
180
+
181
+ if($author) {
182
+ $where = preg_replace('/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(\d+))/', '($1 OR (' . $wpdb->term_taxonomy . '.taxonomy = \''. $this->coauthor_taxonomy.'\' AND '. $wpdb->term_taxonomy .'.term_id = \''. $term->term_id .'\'))', $where, 1); #' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
183
+
184
+ }
185
+ }
186
+ return $where;
 
 
 
187
  }
188
+ /*
189
+ *
190
+ */
191
+ function posts_groupby_filter($groupby){
192
+ global $wpdb;
 
 
 
 
 
 
193
 
194
+ if(is_author()) {
195
+ $groupby = $wpdb->posts .'.ID';
196
+ }
197
+ return $groupby;
198
+ }
199
+
200
+
201
+ /* Update a post's co-authors
202
+ * @param $postID
203
+ * @return
204
+ */
205
+ function coauthors_update_post($post_ID){
206
+ global $current_user;
207
+
208
+ get_currentuserinfo();
209
 
210
+ if($current_user->has_cap('edit_others_posts')){
211
+ $coauthors = $_POST['coauthors'];
212
+ return $this->add_coauthors($post_ID, $coauthors);
213
+ }
214
  }
215
 
216
+ /* Action taken when user is deleted.
217
+ * - User term is removed from all associated posts
218
+ * - Option to specify alternate user in place for each post
219
+ * @param delete_id
220
+ */
221
+ function delete_user_action($delete_id){
222
+ global $wpdb;
223
+
224
+ $reassign_id = absint($_POST['reassign_user']);
225
+
226
+ // If reassign posts, do that -- use coauthors_update_post
227
+ if($reassign_id) {
228
+ // Get posts belonging to deleted author
229
+ $reassign_user = get_profile_by_id('user_login', $reassign_id);
230
+ // Set to new author
231
+ if($reassign_user) {
232
+ $post_ids = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_author = %d", $delete_id) );
233
+
234
+ if ($post_ids) {
235
+ foreach ($post_ids as $post_id) {
236
+ $this->add_coauthors($post_id, array($reassign_user), true);
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ $delete_user = get_profile_by_id('user_login', $delete_id);
243
+ if($delete_user) {
244
+ // Delete term
245
+ wp_delete_term($delete_user, $this->coauthor_taxonomy);
246
+ }
247
  }
248
+
249
+ /* Add a user as coauthor for a post
250
+ *
251
+ */
252
+ function add_coauthors( $post_ID, $coauthors, $append = false ) {
253
+ global $current_user;
254
+
255
+ $post_ID = (int) $post_ID;
256
+
257
+ // if an array isn't returned, create one and populate with default author
258
+ if (!is_array($coauthors) || 0 == count($coauthors) || empty($coauthors)) {
259
+ // @TOOD: create option for default author
260
+ $coauthors = array(get_option('default_author'));
261
+ }
262
+
263
+ // Add each co-author to the post meta
264
+ foreach(array_unique($coauthors) as $author){
265
+
266
+ // Name and slug of term are the username;
267
+ $name = $author;
268
+
269
+ // Add user as a term if they don't exist
270
+ if(!is_term($name, $this->coauthor_taxonomy) ) {
271
+ $args = array('slug' => sanitize_title($name) );
272
+ $insert = wp_insert_term( $name, $this->coauthor_taxonomy, $args );
273
+ }
274
+ }
275
+
276
+ // Add authors as post terms
277
+ if(!is_wp_error($insert)) {
278
+ $set = wp_set_post_terms( $post_ID, $coauthors, $this->coauthor_taxonomy, $append );
279
+ } else {
280
+ // @TODO: error
281
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
+ }
284
+
285
+ /* Main function that handles search-as-you-type
286
+ *
287
+ */
288
+ function ajax_suggest() {
289
+ global $wpdb, $current_user;
290
+
291
+ // Make sure that user is logged in; we don't want to enable direct access
292
+ get_currentuserinfo();
293
+ global $user_level;
294
 
295
+ if($current_user->has_cap('edit_others_posts')) {
296
+
297
+ // Set the minimum level of users to return
298
+ if(!$this->get_plugin_option('allow_subscribers_as_authors')) {
299
+ $user_level_where = "WHERE meta_key = '".$wpdb->prefix."user_level' AND meta_value >= 1";
300
+ }
301
+
302
+ // @TODO validate return
303
+ $q = '%'.strtolower($_REQUEST["q"]).'%';
304
+ if (!$q) return;
305
+
306
+ $authors_query = $wpdb->prepare("SELECT DISTINCT u.ID, u.user_login, u.display_name, u.user_email FROM $wpdb->users AS u"
307
+ ." INNER JOIN $wpdb->usermeta AS um ON u.ID = um.user_id"
308
+ ." WHERE ID = ANY (SELECT user_id FROM $wpdb->usermeta $user_level_where)"
309
+ ." AND (um.meta_key = 'first_name' OR um.meta_key = 'last_name' OR um.meta_key = 'nickname')"
310
+ ." AND (u.user_login LIKE %s"
311
+ ." OR u.user_nicename LIKE %s"
312
+ ." OR u.display_name LIKE %s"
313
+ ." OR u.user_email LIKE %s"
314
+ ." OR um.meta_value LIKE %s)",$q,$q,$q,$q,$q);
315
+
316
+ //echo $authors_query;
317
+ $authors = $wpdb->get_results($authors_query, ARRAY_A);
318
+
319
+ if(is_array($authors)) {
320
+ foreach ($authors as $author) {
321
+ echo $author['ID'] ." | ". $author['user_login']." | ". $author['display_name'] ." | ".$author['user_email'] ."\n";
322
+ }
323
+ }
324
  }
325
+ die();
326
+
327
  }
328
+
329
+ /* Functions to add scripts and css
330
+ * enqueue_scripts is for 2.8+; enqueue_scripts_legacy for > 2.8
331
+ */
332
+ function enqueue_scripts($hook_suffix) {
333
+ global $pagenow;
334
+
335
+ if($this->is_valid_page()) {
336
+ wp_enqueue_style('co-authors-plus', plugins_url('co-authors-plus/admin.css'), false, '', 'all');
337
+ wp_enqueue_script('co-authors-plus', plugins_url('co-authors-plus/admin.js'), array('jquery', 'suggest', 'sack'), '', true);
338
+ }
339
+
340
+
341
+ //wp_dropdown_users(array('name' => 'ef_author', 'include' => $current_user->ID ));
342
+
343
+ }
344
+ function enqueue_scripts_legacy($hook_suffix) {
345
+ global $pagenow;
346
+
347
+ if($this->is_valid_page()) {
348
+ //wp_enqueue_style('co-authors-plus', plugins_url('co-authors-plus/admin.css'), false, '', 'all');
349
+ wp_enqueue_script('co-authors-plus', plugins_url('co-authors-plus/admin.js'), array('jquery', 'suggest', 'sack'), '');
350
+ ?>
351
+ <link type="text/css" rel="stylesheet" href="<?php echo plugins_url('co-authors-plus/admin.css') ?>" media="all" />
352
+ <?php
353
+ }
354
+ }
355
+
356
+ /* Adds necessary javascript variables to admin pages
357
+ *
358
+ */
359
+ function js_vars() {
360
+ global $current_user, $post_ID;
361
+
362
+ get_currentuserinfo();
363
+
364
+ if($this->is_valid_page()) {
365
+ //wp_print_scripts( array( 'sack' ));
366
+ $coauthors = get_coauthors( $post_ID );
367
+ ?>
368
+ <script type="text/javascript">
369
+
370
+ // AJAX link used for the autosuggest
371
+ var coauthor_ajax_suggest_link = "<?php echo 'admin-ajax.php?action=coauthors_ajax_suggest' ?>";
372
+
373
+ if(!i18n || i18n == 'undefined') var i18n = {};
374
+ i18n.coauthors = {};
375
+
376
+ var coauthors_can_edit_others_posts = "<?php echo ($current_user->has_cap('edit_others_posts') ? 'true' : 'false')?>";
377
+
378
+ i18n.coauthors.post_metabox_title = "<?php _e('Post Author(s)', 'co-authors')?>";
379
+ i18n.coauthors.page_metabox_title = "<?php _e('Page Author(s)', 'co-authors')?>";
380
+ i18n.coauthors.edit_label = "<?php _e('Edit', 'co-authors')?>";
381
+ i18n.coauthors.delete_label = "<?php _e('Delete', 'co-authors')?>";
382
+ i18n.coauthors.confirm_delete = "<?php _e('Are you sure you want to delete this author?', 'co-authors')?>";
383
+ i18n.coauthors.input_box_title = "<?php _e('Click to change this author', 'co-authors')?>";
384
+ i18n.coauthors.search_box_text = "<?php _e('Search for an author', 'co-authors')?>";
385
+ i18n.coauthors.help_text = "<?php _e('Click on an author to change them. Click on \"Delete\" to remove them.', 'co-authors')?>";
386
+
387
+ <?php if(is_array($coauthors) && !(empty($coauthors))) : ?>
388
+ var post_coauthors = [
389
+ <?php
390
+ foreach($coauthors as $author) {
391
+ echo "{";
392
+ echo "'login': escape('". $author->user_login ."'),";
393
+ echo "'name': escape('". $author->display_name ."'),";
394
+ echo "'id': '". $author->ID ."'";
395
+ echo "},";
396
+ }
397
+ ?>
398
+ ];
399
+ <?php else : ?>
400
+ var post_coauthors = [
401
+ <?php
402
+ echo "{";
403
+ echo "'login': '". $current_user->user_login ."',";
404
+ echo "'name': '". $current_user->display_name ."',";
405
+ echo "'id': '". $current_user->ID ."'";
406
+ echo "},";
407
+ ?>
408
+ ];
409
+ <?php endif; ?>
410
+ </script>
411
+ <?php
412
+ }
413
+ } // END: js_vars()
414
+
415
+ /* Helper to only add javascript to necessary pages
416
+ * Avoid bloat on admin
417
+ */
418
+ private function is_valid_page() {
419
+ global $pagenow;
420
+
421
+ $pages = array('edit.php', 'post.php', 'post-new.php', 'page.php', 'page-new.php');
422
+
423
+ if(in_array($pagenow, $pages)) return true;
424
+
425
+ return false;
426
+ }
427
+
428
+ /* Allows coauthors to edit the post they're coauthors of
429
+ *
430
+ */
431
+ function add_coauthor_cap( $allcaps, $caps, $args ) {
432
+
433
+ if(in_array('edit_post', $args) || in_array('edit_others_posts', $args)) {
434
+ // @TODO: Fix this disgusting hardcodedness. Ew.
435
+ $user_id = $args[1];
436
+ $post_id = $args[2];
437
+ if(is_coauthor_for_post($user_id, $post_id)) {
438
+ // @TODO check to see if can edit publish posts if post is published
439
+ // @TODO check to see if can edit posts at all
440
+ foreach($caps as $cap) {
441
+ $allcaps[$cap] = 1;
442
+ }
443
+ }
444
+ }
445
+ return $allcaps;
446
+ }
447
+
448
+ /* Emails all coauthors when comment added instead of the main author
449
+ *
450
+ */
451
+ function notify_coauthors( $message_headers, $comment_id ) {
452
+ //echo '<p>Pre:';
453
+ //print_r($message_headers);
454
+ $comment = get_comment($comment_id);
455
+ $post = get_post($comment->comment_post_ID);
456
+ $coauthors = get_coauthors($comment->comment_post_ID);
457
+
458
+ $message_headers .= 'cc: ';
459
+ $count = 0;
460
+ foreach($coauthors as $author) {
461
+ $count++;
462
+ if($author->ID != $post->post_author){
463
+ $message_headers .= $author->user_email;
464
+ if($count < count($coauthors)) $message_headers .= ',';
465
+ }
466
+ }
467
+ $message_headers .= "\n";
468
+ return $message_headers;
469
+ //echo '<p>Post:';
470
+ //print_r($message_headers);
471
+
472
+ }
473
+
474
+ /**
475
+ * Loads options for the plugin.
476
+ * If option doesn't exist in database, it is added
477
+ *
478
+ * Note: default values are stored in the $this->options array
479
+ * Note: a prefix unique to the plugin is appended to all options. Prefix is stored in $this->options_group
480
+ */
481
+ protected function load_options ( ) {
482
 
483
+ $new_options = array();
484
+
485
+ foreach($this->options as $option => $value) {
486
+ $name = $this->get_plugin_option_fullname($option);
487
+ $return = get_option($name);
488
+ if($return === false) {
489
+ add_option($name, $value);
490
+ $new_array[$option] = $value;
491
+ } else {
492
+ $new_array[$option] = $return;
493
+ }
494
+ }
495
+ $this->options = $new_array;
496
+
497
+ } // END: load_options
498
 
 
 
 
 
 
499
 
500
+ /**
501
+ * Returns option for the plugin specified by $name, e.g. custom_stati_enabled
502
+ *
503
+ * Note: The plugin option prefix does not need to be included in $name
504
+ *
505
+ * @param string name of the option
506
+ * @return option|null if not found
507
+ *
508
+ */
509
+ function get_plugin_option ( $name ) {
510
+ if(is_array($this->options) && $option = $this->options[$name])
511
+ return $option;
512
+ else
513
+ return null;
514
+ } // END: get_option
515
+
516
+ // Utility function: appends the option prefix and returns the full name of the option as it is stored in the wp_options db
517
+ protected function get_plugin_option_fullname ( $name ) {
518
+ return $this->options_group . $name;
519
  }
520
+
521
+ /* Adds Settings page for Edit Flow
522
+ *
523
+ */
524
+ function settings_page( ) {
525
+ global $wp_roles;
526
+
527
  ?>
528
+ <div class="wrap">
529
+ <div class="icon32" id="icon-options-general"><br/></div>
530
+ <h2><?php _e('Co-Authors Plus') ?></h2>
531
+
532
+ <form method="post" action="options.php">
533
+ <?php settings_fields($this->options_group); ?>
534
+
535
+ <table class="form-table">
536
+ <tr valign="top">
537
+ <th scope="row"><strong><?php _e('Roles') ?></strong></th>
538
+ <td>
539
+ <p>
540
+ <label for="allow_subscribers_as_authors">
541
+ <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') ?>
542
+ </label> <br />
543
+ <span class="description"><?php _e('Enabling this option will allow you to add users with the subscriber role as authors for posts.') ?></span>
544
+ </p>
545
+ </td>
546
+ </tr>
547
+
548
+ </table>
549
+
550
+ <p class="submit">
551
+ <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
552
+ </p>
553
+ </form>
554
+ </div>
555
+ <?php
556
  }
557
+
558
+
559
+ /* Function updates coauthors from old meta-based storage to taxonomy-based
560
+ *
561
+ */
562
+ function update() {
563
+ // Get all posts with meta_key _coauthor
564
+ $all_posts = get_posts(array('numberposts' => '-1'));
565
+
566
+ //echo '<p>returned posts ('.count($all_posts).'):</p>';
567
+ //print_r($posts);
568
+ //echo '<hr />';
569
+
570
+ if(is_array($all_posts)) {
571
+ foreach($all_posts as $single_post) {
572
+
573
+ // create new array
574
+ $coauthors = array();
575
+ // get author id -- try to use get_profile
576
+ $coauthors[] = get_profile_by_id('user_login', (int)$single_post->post_author);
577
+ // get coauthors id
578
+ $legacy_coauthors = get_post_meta($single_post->ID, '_coauthor');
579
+ //print_r($legacy_coauthors);
580
+ //echo '<hr />';
581
+ if(is_array($legacy_coauthors)) {
582
+ //echo '<p>Has Legacy coauthors';
583
+ foreach($legacy_coauthors as $legacy_coauthor) {
584
+ $legacy_coauthor_login = get_profile_by_id('user_login', (int)$legacy_coauthor);
585
+ if($legacy_coauthor_login) $coauthors[] = $legacy_coauthor_login;
586
+ }
587
+ } else {
588
+ //echo '<p>No Legacy coauthors';
589
+ }
590
+ //echo '<p>Post '.$single_post->ID;
591
+ //print_r($coauthors);
592
+ //echo '<hr />';
593
+ $this->add_coauthors($single_post->ID, $coauthors);
594
+
595
+ }
596
+ }
597
+ }
598
+
599
+ /*
600
+ * @TODO
601
+ * - Add new author
602
+ * - Add search-as-you-type to QuikcEdit
603
+ * get_coauthor_meta function
604
+ */
605
 
606
  }
607
 
608
+ /** Helper Functions **/
 
 
 
609
 
610
+ /* Replacement for the default WordPress get_profile function, since that doesn't allow for search by user_id
611
+ * Returns a the specified column value for the specified user
612
+ */
 
 
613
 
614
+ if(!function_exists('get_profile_by_id')) {
615
+ function get_profile_by_id($field, $user_id) {
616
+ global $wpdb;
617
+ if($field && $user_id) return $wpdb->get_var( $wpdb->prepare("SELECT $field FROM $wpdb->users WHERE ID = %d", $user_id) );
618
+ return false;
619
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
  }
621
 
622
+ /** Let's get the plugin rolling **/
 
 
 
 
 
 
 
 
 
 
623
 
624
+ // Create new instance of the edit_flow object
625
+ global $coauthors_plus;
626
+ $coauthors_plus = new coauthors_plus();
627
+ //$coauthors_plus->update();
628
+
629
+ // Core hooks to initialize the plugin
630
+ add_action('init', array(&$coauthors_plus,'init'));
631
+ add_action('admin_init', array(&$coauthors_plus,'admin_init'));
632
+
633
+ // Hook to perform action when plugin activated
634
+ register_activation_hook( __FILE__, array(&$edit_flow, 'activate_plugin'));
635
+
636
+ // Upgrade to new taxonomy system
637
+ if(floatval(get_option('coauthors_plus_version')) < 2.0) $coauthors_plus->update();
 
 
 
 
 
 
 
 
 
 
638
 
639
+ update_option('coauthors_plus_version', COAUTHORS_PLUS_VERSION);
640
+
641
  ?>
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Co-Authors Plus ===
2
  Contributors: batmoo
3
  Donate link: http://digitalize.ca/donate
4
- Tags: authors, users
5
  Tested up to: 2.8
6
  Requires at least: 2.6
7
- Stable tag: 1.2
8
 
9
  Allows multiple authors to be assigned to a Post or Page via search-as-you-type input boxes.
10
 
@@ -12,16 +12,27 @@ Allows multiple authors to be assigned to a Post or Page via search-as-you-type
12
 
13
  Allows multiple authors to be assigned to a Post or Page via the search-as-you-type inputs. Co-authored posts appear on a co-author's posts page and feed. New template tags allow listing of co-authors. Editors and Administrators may assign co-authors to a post. Additionally, co-authors may edit the posts they are associated with, and co-authors who are contributors may only edit posts if they have not been published (as is usual).
14
 
15
- This plugin is an extended version of the Co-Authors plugin originally developed at [Shepherd Interactive](http://www.shepherd-interactive.com/ "Shepherd Interactive specializes in web design and development in Portland, Oregon") (2007). Their plugin was inspired by 'Multiple Authors' plugin by Mark Jaquith (2005).
16
 
17
  The extended version is created by [Mohammad Jangda](http://digitalize.ca), and incorporates search-as-you-type functionality for adding users, which aims to make easy the task of adding multiple users to posts and pages, especially when dealing with a system with hundreds of users (typical of newspaper and magazine sites).
 
 
18
 
19
  > *See "Other Notes" section for Template Tags and usage information*
20
 
21
- = Changelog =
22
 
23
- *2009-06-16 / 1.2.0*
 
 
 
 
 
 
 
 
24
 
 
25
  * FIX: Added compatibility for WordPress 2.8
26
  * FIX: Added new template tags (get_the_coauthor_meta & the_coauthor_meta) to fix issues related to displaying author info on author archive pages. See [Other Notes](http://wordpress.org/extend/plugins/co-authors-plus/other_notes/) for details.
27
  * FIX: Plugin should now work for plugins not using the 'wp_' DB prefix
@@ -29,35 +40,29 @@ The extended version is created by [Mohammad Jangda](http://digitalize.ca), and
29
  * FIX: Plugin now used WordPress native AJAX calls to tighten security
30
  * DOCS: Added details about the new template tags
31
 
32
- *2009-04-26 / 1.1.5*
33
-
34
  * FIX: Not searching Updated SQL query for autosuggest to search through first name, last name, and nickname
35
  * FIX: When editing an author, and clicking on a suggested author, the original author was not be removed
36
  * DOCS: Added code comments to javascript; more still to be added
37
  * DOCS: Updated readme information
38
 
39
- *2009-04-25 / 1.1.4*
40
-
41
  * Disabled "New Author" output in suggest box, for now
42
  * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
43
 
44
- *2009-04-23 / 1.1.3*
45
-
46
  * Add blur event to disable input box
47
  * Limit only one edit at a time.
48
  * Checked basic cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
49
  * Add suggest javascript plugin to Edit Page.
50
 
51
- *2009-04-19 / 1.1.2*
52
-
53
  * Disabled form submit when enter pressed.
54
 
55
- *2009-04-15 / 1.1.1*
56
-
57
  * Changed SQL query to return only contributer-level and above users.
58
 
59
- *2009-04-14: 1.1.0*
60
-
61
  * Initial beta release.
62
 
63
 
@@ -134,14 +139,24 @@ For example:
134
  the_author();
135
  }
136
 
137
- = NEW (2009-06-16): (the coauthor meta) Template Tags =
138
-
139
- *Two new template tags were added to fix issues related to displaying author info on an Author Archive page:*
140
 
141
  * <code>get_the_coauthor_meta( $field )</code> (2.8 only)
142
  * <code>the_coauthor_meta( $field )</code> (2.8 only)
143
 
144
- Note: These will only work on Author Archive pages and with WordPress 2.8 only. The $field variable corresponds with the same values accepted by the [the author meta](http://codex.wordpress.org/Template_Tags/the_author_meta) function
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
 
147
 
@@ -151,13 +166,9 @@ Note: These will only work on Author Archive pages and with WordPress 2.8 only.
151
 
152
  The most notable difference is the replacement of the standard WordPress authors drop-downs with search-as-you-type/auto-suggest/whatever-you-call-them input boxes. As a result, major bits of the JavaScript code was changed to be more jQuery-friendly. Eventually, I hope to include the ability to add new Users from within the Edit Post/Page screen and possibly Gravatar support.
153
 
154
- = When will the "New Author" function be added? =
155
-
156
- Hopefully soon.
157
-
158
  = What happens to posts and pages when I delete a user assigned to a post or page as a coauthor? =
159
 
160
- When a user is deleted from WordPress, they will be removed from all of posts for which they are co-authors.
161
 
162
  == Screenshots ==
163
  1. "Post Author(s)" box with multiple authors added
1
  === Co-Authors Plus ===
2
  Contributors: batmoo
3
  Donate link: http://digitalize.ca/donate
4
+ Tags: authors, users, multiple authors, coauthors, multi-author
5
  Tested up to: 2.8
6
  Requires at least: 2.6
7
+ Stable tag: 2.0
8
 
9
  Allows multiple authors to be assigned to a Post or Page via search-as-you-type input boxes.
10
 
12
 
13
  Allows multiple authors to be assigned to a Post or Page via the search-as-you-type inputs. Co-authored posts appear on a co-author's posts page and feed. New template tags allow listing of co-authors. Editors and Administrators may assign co-authors to a post. Additionally, co-authors may edit the posts they are associated with, and co-authors who are contributors may only edit posts if they have not been published (as is usual).
14
 
15
+ This plugin is an almost complete rewrite of the Co-Authors plugin originally developed at [Shepherd Interactive](http://www.shepherd-interactive.com/ "Shepherd Interactive specializes in web design and development in Portland, Oregon") (2007). Their plugin was inspired by 'Multiple Authors' plugin by Mark Jaquith (2005).
16
 
17
  The extended version is created by [Mohammad Jangda](http://digitalize.ca), and incorporates search-as-you-type functionality for adding users, which aims to make easy the task of adding multiple users to posts and pages, especially when dealing with a system with hundreds of users (typical of newspaper and magazine sites).
18
+
19
+ Version 2.0 is a major re-write of the plugin to utilize the WordPress taxonomy system instead of post meta.
20
 
21
  > *See "Other Notes" section for Template Tags and usage information*
22
 
23
+ == Changelog ==
24
 
25
+ =2009-10-11 / 2.0=
26
+ * Plugin mostly rewritten to make use of taxonomy instead of post_meta
27
+ * Can now see all authors of a post under the author column from Edit Posts page
28
+ * All authors of a post are now notified on a new comment
29
+ * Various javascript enhancements
30
+ * New option to allow subscribers to be added as authors
31
+ * All Authors can edit they posts of which they are coauthors
32
+ * FIX: Issues with wp_coauthors_list function
33
+ * FIX: Issues with coauthored posts not showing up on author archives
34
 
35
+ =2009-06-16 / 1.2.0=
36
  * FIX: Added compatibility for WordPress 2.8
37
  * FIX: Added new template tags (get_the_coauthor_meta & the_coauthor_meta) to fix issues related to displaying author info on author archive pages. See [Other Notes](http://wordpress.org/extend/plugins/co-authors-plus/other_notes/) for details.
38
  * FIX: Plugin should now work for plugins not using the 'wp_' DB prefix
40
  * FIX: Plugin now used WordPress native AJAX calls to tighten security
41
  * DOCS: Added details about the new template tags
42
 
43
+ =2009-04-26 / 1.1.5=
 
44
  * FIX: Not searching Updated SQL query for autosuggest to search through first name, last name, and nickname
45
  * FIX: When editing an author, and clicking on a suggested author, the original author was not be removed
46
  * DOCS: Added code comments to javascript; more still to be added
47
  * DOCS: Updated readme information
48
 
49
+ =2009-04-25 / 1.1.4=
 
50
  * Disabled "New Author" output in suggest box, for now
51
  * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
52
 
53
+ =2009-04-23 / 1.1.3=
 
54
  * Add blur event to disable input box
55
  * Limit only one edit at a time.
56
  * Checked basic cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
57
  * Add suggest javascript plugin to Edit Page.
58
 
59
+ =2009-04-19 / 1.1.2=
 
60
  * Disabled form submit when enter pressed.
61
 
62
+ =2009-04-15 / 1.1.1=
 
63
  * Changed SQL query to return only contributer-level and above users.
64
 
65
+ =2009-04-14: 1.1.0=
 
66
  * Initial beta release.
67
 
68
 
139
  the_author();
140
  }
141
 
142
+ = the coauthor meta =
 
 
143
 
144
  * <code>get_the_coauthor_meta( $field )</code> (2.8 only)
145
  * <code>the_coauthor_meta( $field )</code> (2.8 only)
146
 
147
+ Note: The $field variable corresponds with the same values accepted by the [the author meta](http://codex.wordpress.org/Template_Tags/the_author_meta) function
148
+
149
+ = get coauthors =
150
+
151
+ * <code>get_coauthors( [$post_id], [$args] )</code>
152
+
153
+ This function returns an array of coauthors for the specified post, or if used inside the Loop, the current post active in the Loop. the $args paramater is an array that allows you to specify the order in which the authors should be returned.
154
+
155
+ = is coauthor for post =
156
+
157
+ * <code>is_coauthor_for_post( $user, $post_id )</code>
158
+
159
+ This function allows you to check whether the specified user is coauthor for a post. The $user attribute can be the user ID or username.
160
 
161
 
162
 
166
 
167
  The most notable difference is the replacement of the standard WordPress authors drop-downs with search-as-you-type/auto-suggest/whatever-you-call-them input boxes. As a result, major bits of the JavaScript code was changed to be more jQuery-friendly. Eventually, I hope to include the ability to add new Users from within the Edit Post/Page screen and possibly Gravatar support.
168
 
 
 
 
 
169
  = What happens to posts and pages when I delete a user assigned to a post or page as a coauthor? =
170
 
171
+ When a user is deleted from WordPress, they will be removed from all of posts for which they are co-authors. If you chose to reassign their posts to another user, that user will be set as the coauthor instead.
172
 
173
  == Screenshots ==
174
  1. "Post Author(s)" box with multiple authors added
suggest.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- /**
3
- * Bootstrap for getting the ABSPATH constant to wp-load.php
4
- * This is requried when a plugin requires access not via the admin screen.
5
- *
6
- * If the wp-load.php file is not found, then an error will be displayed
7
- *
8
- */
9
-
10
- /** Define the server path to the file wp-config here, if you placed WP-CONTENT outside the classic file structure */
11
-
12
- $path = ''; // It should be end with a trailing slash
13
-
14
- /** That's all, stop editing from here **/
15
-
16
- if ( !defined('WP_LOAD_PATH') ) {
17
-
18
- /** classic root path if wp-content and plugins is below wp-config.php */
19
- $classic_root = dirname(dirname(dirname(dirname(__FILE__)))) . '/' ;
20
-
21
- if (file_exists( $classic_root . 'wp-load.php') )
22
- define( 'WP_LOAD_PATH', $classic_root);
23
- else
24
- if (file_exists( $path . 'wp-load.php') )
25
- define( 'WP_LOAD_PATH', $path);
26
- else
27
- exit("Could not find wp-load.php");
28
- }
29
-
30
- // let's load WordPress
31
- require_once( WP_LOAD_PATH . 'wp-load.php');
32
-
33
-
34
- /**
35
- * Returns a listing of users based on search string.
36
- * Searches through user's login, full name, display name, and email for string match
37
- *
38
- */
39
- function coauthors_ajax_suggest() {
40
-
41
- global $wpdb;
42
-
43
- $q = '%'.strtolower($_REQUEST["q"]).'%';
44
- if (!$q) return;
45
-
46
- // Prepare search query
47
- $authors_query = $wpdb->prepare("SELECT DISTINCT u.ID, u.display_name, u.user_email FROM $wpdb->users AS u
48
- INNER JOIN $wpdb->usermeta AS um ON u.ID = um.user_id
49
- WHERE ID = ANY (SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'wp_user_level' AND meta_value >= 1)
50
- AND (um.meta_key = 'first_name' OR um.meta_key = 'last_name' OR um.meta_key = 'nickname')
51
- AND (u.user_login LIKE %s
52
- OR u.user_nicename LIKE %s
53
- OR u.display_name LIKE %s
54
- OR u.user_email LIKE %s
55
- OR um.meta_value LIKE %s)",$q,$q,$q,$q,$q);
56
-
57
- $authors = $wpdb->get_results($authors_query, ARRAY_A);
58
-
59
- if(is_array($authors)) {
60
- foreach ($authors as $author) {
61
-
62
- echo $author['ID']." | ". $author['display_name'] ." | ".$author['user_email'] ."\n";
63
- }
64
- } else {
65
-
66
- }
67
- // Return output to create new author
68
- //echo "New | Add new author: ".trim($q,'%')."\n";
69
- }
70
-
71
- // Make sure that user is logged in; we don't want to enable direct access
72
- get_currentuserinfo();
73
- global $user_level;
74
- if ($user_level >= 7) coauthors_ajax_suggest();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
template-tags.php ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function get_coauthors( $post_id = 0, $args = array() ) {
4
+ global $post, $post_ID, $coauthors_plus, $wpdb;
5
+
6
+ $coauthors = array();
7
+ $post_id = (int)$post_id;
8
+ if(!$post_id && $post_ID) $post_id = $post_ID;
9
+ if(!$post_id && $post) $post_id = $post->ID;
10
+
11
+ $defaults = array('orderby'=>'term_order', 'order'=>'ASC');
12
+ $args = wp_parse_args( $args, $defaults );
13
+
14
+ if($post_id) {
15
+ $coauthor_terms = wp_get_post_terms( $post_id, $coauthors_plus->coauthor_taxonomy, $args );
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
+ }
23
+ } else {
24
+ if($post) {
25
+ $post_author = get_userdata($post->post_author);
26
+ } else {
27
+ $post_author = get_userdata($wpdb->get_var($wpdb->prepare("SELECT post_author FROM $wpdb->posts WHERE ID = %d", $post_id)));
28
+ }
29
+ if(!empty($post_author)) $coauthors[] = $post_author;
30
+ }
31
+ }
32
+ return $coauthors;
33
+ }
34
+
35
+ function is_coauthor_for_post( $user, $post_id = 0 ) {
36
+ // @TODO Make this work in or out of loop
37
+ $coauthors = get_coauthors($post_id);
38
+ if(is_numeric($user)) $user = get_userdata($user)->user_login;
39
+ foreach($coauthors as $coauthor) {
40
+ if($user == $coauthor->user_login) return true;
41
+ }
42
+ return false;
43
+ }
44
+
45
+ class CoAuthorsIterator {
46
+ var $position = -1;
47
+ var $original_authordata;
48
+ var $authordata_array;
49
+ var $count;
50
+
51
+ function CoAuthorsIterator($postID = 0){
52
+ global $post, $authordata, $wpdb;
53
+ $postID = (int)$postID;
54
+ if(!$postID && $post)
55
+ $postID = (int)$post->ID;
56
+ if(!$postID)
57
+ trigger_error(__('No post ID provided for CoAuthorsIterator constructor. Are you not in a loop or is $post not set?', 'co-authors')); //return null;
58
+
59
+ $this->original_authordata = $authordata;
60
+ $this->authordata_array = get_coauthors($postID);
61
+
62
+ $this->count = count($this->authordata_array);
63
+ }
64
+
65
+ function iterate(){
66
+ global $authordata;
67
+ $this->position++;
68
+
69
+ //At the end of the loop
70
+ if($this->position > $this->count-1){
71
+ $authordata = $this->original_authordata;
72
+ $this->position = -1;
73
+ return false;
74
+ }
75
+
76
+ //At the beginning of the loop
77
+ if($this->position == 0 && !empty($authordata))
78
+ $this->original_authordata = $authordata;
79
+
80
+ $authordata = $this->authordata_array[$this->position];
81
+
82
+ return true;
83
+ }
84
+
85
+ function get_position(){
86
+ if($this->position === -1)
87
+ return false;
88
+ return $this->position;
89
+ }
90
+ function is_last(){
91
+ return $this->position === $this->count-1;
92
+ }
93
+ function is_first(){
94
+ return $this->position === 0;
95
+ }
96
+ function count(){
97
+ return $this->count;
98
+ }
99
+ function get_all(){
100
+ return $this->authordata_array;
101
+ }
102
+ }
103
+
104
+ //Helper function for the following new template tags
105
+ function coauthors__echo($tag, $between, $betweenLast, $before, $after){
106
+ $i = new CoAuthorsIterator();
107
+ echo $before;
108
+ if($i->iterate())
109
+ $tag();
110
+ while($i->iterate()){
111
+ echo $i->is_last() ? $betweenLast : $between;
112
+ $tag();
113
+ }
114
+ echo $after;
115
+ }
116
+ function coauthors__return($tag){
117
+ $return = array();
118
+ $i = new CoAuthorsIterator();
119
+ if($i->iterate())
120
+ $return[] = $tag();
121
+ while($i->iterate()){
122
+ $return[] = $tag();
123
+ }
124
+ echo $after;
125
+ }
126
+
127
+ //Provide co-author equivalents to the existing author template tags
128
+ function coauthors($between = null, $betweenLast = null, $before = null, $after = null){
129
+ if($between === NULL)
130
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
131
+ if($betweenLast === NULL)
132
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
133
+ if($before === NULL)
134
+ $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
135
+ if($after === NULL)
136
+ $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
137
+ coauthors__echo('the_author', $between, $betweenLast, $before, $after);
138
+ }
139
+ function coauthors_posts_links($between = null, $betweenLast = null, $before = null, $after = null){
140
+ if($between === NULL)
141
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
142
+ if($betweenLast === NULL)
143
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
144
+ if($before === NULL)
145
+ $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
146
+ if($after === NULL)
147
+ $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
148
+ coauthors__echo('the_author_posts_link', $between, $betweenLast, $before, $after);
149
+ }
150
+ function coauthors_firstnames($between = null, $betweenLast = null, $before = null, $after = null){
151
+ if($between === NULL)
152
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
153
+ if($betweenLast === NULL)
154
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
155
+ if($before === NULL)
156
+ $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
157
+ if($after === NULL)
158
+ $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
159
+ coauthors__echo('the_author_firstname', $between, $betweenLast, $before, $after);
160
+ }
161
+ function coauthors_lastnames($between = null, $betweenLast = null, $before = null, $after = null){
162
+ if($between === NULL)
163
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
164
+ if($betweenLast === NULL)
165
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
166
+ if($before === NULL)
167
+ $before = COAUTHORS_DEFAULT_BEFORE;
168
+ if($after === NULL)
169
+ $after = COAUTHORS_DEFAULT_AFTER;
170
+ coauthors__echo('the_author_lastname', $between, $betweenLast, $before, $after);
171
+ }
172
+ function coauthors_nicknames($between = null, $betweenLast = null, $before = null, $after = null){
173
+ if($between === NULL)
174
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
175
+ if($betweenLast === NULL)
176
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
177
+ if($before === NULL)
178
+ $before = COAUTHORS_DEFAULT_BEFORE;
179
+ if($after === NULL)
180
+ $after = COAUTHORS_DEFAULT_AFTER;
181
+ coauthors__echo('the_author_nickname', $between, $betweenLast, $before, $after);
182
+ }
183
+ function coauthors_links($between = null, $betweenLast = null, $before = null, $after = null){
184
+ if($between === NULL)
185
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
186
+ if($betweenLast === NULL)
187
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
188
+ if($before === NULL)
189
+ $before = COAUTHORS_DEFAULT_BEFORE; //__(COAUTHORS_DEFAULT_BEFORE, 'co-authors');
190
+ if($after === NULL)
191
+ $after = COAUTHORS_DEFAULT_AFTER; //__(COAUTHORS_DEFAULT_AFTER, 'co-authors');
192
+ coauthors__echo('the_author_link', $between, $betweenLast, $before, $after);
193
+ }
194
+ function coauthors_IDs($between = null, $betweenLast = null, $before = null, $after = null){
195
+ if($between === NULL)
196
+ $between = __(COAUTHORS_DEFAULT_BETWEEN, 'co-authors');
197
+ if($betweenLast === NULL)
198
+ $betweenLast = __(COAUTHORS_DEFAULT_BETWEEN_LAST, 'co-authors');
199
+ if($before === NULL)
200
+ $before = COAUTHORS_DEFAULT_BEFORE;
201
+ if($after === NULL)
202
+ $after = COAUTHORS_DEFAULT_AFTER;
203
+ coauthors__echo('the_author_ID', $between, $betweenLast, $before, $after);
204
+ }
205
+ // @TODO: fix this function
206
+ function get_the_coauthor_meta( $field, $user_id = 0 ) {
207
+ global $wp_query, $post;
208
+
209
+ // inside loop
210
+ if($post) {
211
+ //use iterator and loop through meta
212
+
213
+ } else {
214
+ // use regular
215
+ if($user_id) {
216
+ //$curauth = $wp_query->get_queried_object();
217
+
218
+ if(function_exists('get_the_author_meta')) {//get_bloginfo('version') >= 2.8) {
219
+ return get_the_author_meta('description', $user_id);
220
+ }
221
+ }
222
+ }
223
+ }
224
+
225
+ function the_coauthor_meta( $field, $user_id = 0 ) {
226
+ // need before after options
227
+ echo get_the_coauthor_meta($field, $user_id);
228
+ }
229
+
230
+ //customized wp_list_authors() from WP core
231
+ /**
232
+ * List all the *co-authors* of the blog, with several options available.
233
+ * optioncount (boolean) (false): Show the count in parenthesis next to the author's name.
234
+ * exclude_admin (boolean) (true): Exclude the 'admin' user that is installed by default.
235
+ * show_fullname (boolean) (false): Show their full names.
236
+ * hide_empty (boolean) (true): Don't show authors without any posts.
237
+ * feed (string) (''): If isn't empty, show links to author's feeds.
238
+ * feed_image (string) (''): If isn't empty, use this image to link to feeds.
239
+ * echo (boolean) (true): Set to false to return the output, instead of echoing.
240
+ * @param array $args The argument array.
241
+ * @return null|string The output, if echo is set to false.
242
+ */
243
+ function coauthors_wp_list_authors($args = '') {
244
+ global $wpdb, $coauthors_plus;
245
+
246
+ $defaults = array(
247
+ 'optioncount' => false, 'exclude_admin' => true,
248
+ 'show_fullname' => false, 'hide_empty' => true,
249
+ 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true,
250
+ 'style' => 'list', 'html' => true
251
+ );
252
+
253
+ $r = wp_parse_args( $args, $defaults );
254
+ extract($r, EXTR_SKIP);
255
+ $return = '';
256
+
257
+ // @todo Move select to get_authors()
258
+ $authors = $wpdb->get_results("SELECT ID, user_nicename from $wpdb->users " . ($exclude_admin ? "WHERE user_login <> 'admin' " : '') . "ORDER BY display_name");
259
+
260
+ $author_count = array();
261
+
262
+ $query = "SELECT DISTINCT $wpdb->users.ID AS post_author, $wpdb->terms.name AS user_name, $wpdb->term_taxonomy.count AS count";
263
+ $query .= " FROM $wpdb->posts";
264
+ $query .= " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)";
265
+ $query .= " INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
266
+ $query .= " INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)";
267
+ $query .= " INNER JOIN $wpdb->users ON ($wpdb->terms.name = $wpdb->users.user_login)";
268
+ $query .= " WHERE post_type = 'post' AND " . get_private_posts_cap_sql( 'post' );
269
+ $query .= " AND $wpdb->term_taxonomy.taxonomy = '$coauthors_plus->coauthor_taxonomy'";
270
+ $query .= " GROUP BY post_author";
271
+
272
+ foreach ((array) $wpdb->get_results($query) as $row) {
273
+ $author_count[$row->post_author] = $row->count;
274
+ }
275
+
276
+ foreach ( (array) $authors as $author ) {
277
+
278
+ $link = '';
279
+
280
+ $author = get_userdata( $author->ID );
281
+ $posts = (isset($author_count[$author->ID])) ? $author_count[$author->ID] : 0;
282
+ $name = $author->display_name;
283
+
284
+ if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
285
+ $name = "$author->first_name $author->last_name";
286
+
287
+ if( !$html ) {
288
+ if ( $posts == 0 ) {
289
+ if ( ! $hide_empty )
290
+ $return .= $name . ', ';
291
+ } else
292
+ $return .= $name . ', ';
293
+
294
+ // No need to go further to process HTML.
295
+ continue;
296
+ }
297
+
298
+ if ( !($posts == 0 && $hide_empty) && 'list' == $style )
299
+ $return .= '<li>';
300
+ if ( $posts == 0 ) {
301
+ if ( ! $hide_empty )
302
+ $link = $name;
303
+ } else {
304
+ $link = '<a href="' . get_author_posts_url($author->ID, $author->user_nicename) . '" title="' . esc_attr( sprintf(__("Posts by %s"), $author->display_name) ) . '">' . $name . '</a>';
305
+
306
+ if ( (! empty($feed_image)) || (! empty($feed)) ) {
307
+ $link .= ' ';
308
+ if (empty($feed_image))
309
+ $link .= '(';
310
+ $link .= '<a href="' . get_author_feed_link($author->ID) . '"';
311
+
312
+ if ( !empty($feed) ) {
313
+ $title = ' title="' . esc_attr($feed) . '"';
314
+ $alt = ' alt="' . esc_attr($feed) . '"';
315
+ $name = $feed;
316
+ $link .= $title;
317
+ }
318
+
319
+ $link .= '>';
320
+
321
+ if ( !empty($feed_image) )
322
+ $link .= "<img src=\"" . esc_url($feed_image) . "\" style=\"border: none;\"$alt$title" . ' />';
323
+ else
324
+ $link .= $name;
325
+
326
+ $link .= '</a>';
327
+
328
+ if ( empty($feed_image) )
329
+ $link .= ')';
330
+ }
331
+
332
+ if ( $optioncount )
333
+ $link .= ' ('. $posts . ')';
334
+
335
+ }
336
+
337
+ if ( !($posts == 0 && $hide_empty) && 'list' == $style )
338
+ $return .= $link . '</li>';
339
+ else if ( ! $hide_empty )
340
+ $return .= $link . ', ';
341
+ }
342
+
343
+ $return = trim($return, ', ');
344
+
345
+ if ( ! $echo )
346
+ return $return;
347
+ echo $return;
348
+ }
349
+
350
+
351
+ ?>