Co-Authors Plus - Version 3.4.6

Version Description

Download this release

Release Info

Developer automattic
Plugin Icon wp plugin Co-Authors Plus
Version 3.4.6
Comparing to
See all releases

Code changes from version 3.4.5 to 3.4.6

.editorconfig ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is for unifying the coding style for different editors and IDEs
2
+ # editorconfig.org
3
+
4
+ # WordPress Coding Standards
5
+ # https://make.wordpress.org/core/handbook/coding-standards/
6
+
7
+ root = true
8
+
9
+ [*]
10
+ charset = utf-8
11
+ end_of_line = lf
12
+ indent_size = 4
13
+ tab_width = 4
14
+ indent_style = tab
15
+ insert_final_newline = true
16
+ trim_trailing_whitespace = true
17
+
18
+ [*.txt]
19
+ trim_trailing_whitespace = false
20
+
21
+ [*.{md,json,yml}]
22
+ trim_trailing_whitespace = false
23
+ indent_style = space
24
+ indent_size = 2
.gitignore CHANGED
@@ -2,3 +2,5 @@
2
  .svn
3
  .idea/
4
  wpcom-helper.php
 
 
2
  .svn
3
  .idea/
4
  wpcom-helper.php
5
+ /composer.lock
6
+ /vendor
.travis.yml DELETED
@@ -1,69 +0,0 @@
1
- language: php
2
- services: mysql
3
-
4
- matrix:
5
- include:
6
- # aliased to a recent 5.6.x version
7
- - php: "5.6"
8
- env: WP_VERSION=5.6.1
9
-
10
- - php: '5.6'
11
- env:
12
- - WP_VERSION=latest
13
- #- SNIFF=1
14
- - WP_MULTISITE=0
15
-
16
- - php: '5.6'
17
- env:
18
- - WP_VERSION=latest
19
- #- SNIFF=1
20
- - WP_MULTISITE=1
21
-
22
- # aliased to a recent 7.x version
23
- - php: '7.0'
24
- env: WP_VERSION=5.6.1
25
-
26
- - php: '7.0'
27
- env: WP_VERSION=latest
28
-
29
- - php: '7.1'
30
- env: WP_VERSION=5.6.1
31
-
32
- - php: '7.1'
33
- env: WP_VERSION=latest
34
-
35
- before_script:
36
- # Set up CodeSniffer
37
- - export PHPCS_DIR=/tmp/phpcs
38
- - export SNIFFS_DIR=/tmp/sniffs
39
- # Install CodeSniffer for WordPress Coding Standards checks.
40
- - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi
41
- # Install WordPress Coding Standards.
42
- - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $SNIFFS_DIR; fi
43
- # Install VIP Coding Standards.
44
- - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/Automattic/VIP-Coding-Standards.git $SNIFFS_DIR; fi
45
- # Install PHP Compatibility sniffs.
46
- - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/wimg/PHPCompatibility.git $SNIFFS_DIR/PHPCompatibility; fi
47
- # Set install path for PHPCS sniffs.
48
- # @link https://github.com/squizlabs/PHP_CodeSniffer/blob/4237c2fc98cc838730b76ee9cee316f99286a2a7/CodeSniffer.php#L1941
49
- - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs --config-set installed_paths $SNIFFS_DIR; fi
50
- # After CodeSniffer install you should refresh your path.
51
- - if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi
52
- # Set up unit tests
53
- - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
54
- # Properly handle versions since the pre-installed PHPUnit is incompatible on some builds
55
- - composer require --dev "phpunit/phpunit":"^5"
56
-
57
- script:
58
- # WordPress Coding Standards.
59
- # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
60
- # @link http://pear.php.net/package/PHP_CodeSniffer/
61
- # -p flag: Show progress of the run.
62
- # -s flag: Show sniff codes in all reports.
63
- # -v flag: Print verbose output.
64
- # -n flag: Do not print warnings. (shortcut for --warning-severity=0)
65
- # --standard: Use WordPress as the standard.
66
- # --extensions: Only sniff PHP files.
67
- - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs -p -s -v -n . --standard="WordPress-VIP-Go" --extensions=php; fi
68
- # Run unit tests
69
- - ./vendor/bin/phpunit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
CHANGELOG.md ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog for Co-Authors Plus
2
+
3
+ **3.4.6 (May 28, 2021)**
4
+
5
+ * Gravatars for guest authors now display in author select box #767
6
+ * Fix non-functional filter button on Guest Author listing page #768
7
+ * Added Hebrew translation strings #772
8
+ * Improve code style via PHPCBF #771 and .editorconfig #773
9
+ * Fix bug where guest author with pipe character in name is not rendered in author select box #775
10
+ * Fix `get_coauthor_by()` for correct return of users prefixed with "Cap" in name #778
11
+ * Correct failing unit tests under WP 5.7 #774
12
+ * Linked accounts display more accurate counts #776
13
+ * Switch to GitHub Actions from TravisCI #784
14
+ * Update .gitignore to exclude composer lock file and vendor dir #787
15
+ * Hide author section in Gutenberg for WP 5.7+ #793
16
+ * Delete correct CAP associated term on user delete #792
17
+ * Move changelog out of readme #768
18
+
19
+ **3.4.5 (Mar. 28, 2021)**
20
+ * Fixed bug where guest authors with spaces in names were not showing when queried in AJAX suggest box #764
21
+
22
+ **3.4.4 (Mar. 26, 2021)**
23
+ * Fixed bug where author with slug beginning with "cap" does not appear in bylines AJAX suggest box when queried #744
24
+ * Travis for Xenial build no longer fails #751
25
+ * Unit tests no longer fail #752
26
+ * Fixed REST permissions bug where co-author cannot view post assigned to them in Gutenberg #757
27
+
28
+ **3.4.3 (Apr. 20, 2020)**
29
+ * Added author support to CPT instructions in readme FAQ #720
30
+ * Added object check for user in `coauthors_set_post_author_field()` #721
31
+ * Fix inefficient user query in avatar url hook #724
32
+ * Fix operand typo in `get_guest_author_thumbnail()` for adding custom classes #725
33
+ * Remove hardcoded default avatar and use default option #728
34
+
35
+ **3.4.2 (Dec. 16, 2019)**
36
+ * Fix incorrect user avatar being displayed from featured post image #706
37
+ * Add check for `filter_get_avatar_url` to ensure valid second parameter #707
38
+ * `add_coauthors()` accepts ID parameter now #685 and ensures valid term slug used #708
39
+ * `filter_count_user_posts` checks that user ID returns valid user object #714
40
+ * Added post count instructions in readme FAQ for CPTs #713
41
+
42
+ **3.4.1 (Aug. 19, 2019)**
43
+ * Fix an issue that may arise in bulk edit #700
44
+
45
+ **3.4 (May 6, 2019)**
46
+ * New filter `get_coauthors` for modifying coauthor data returned in `get_coauthors()` #646
47
+ * New filter `coauthors_guest_authors_exported_extra_data` to allow guest author to export data as regular author #528
48
+ * New filter `get_avatar_url()` to show avatar in JS selection #621
49
+ * New parameter in `coauthors_wp_list_authors()` to only query authors with posts #496
50
+ * Add internationalization support to title and name in author archives #516
51
+ * Add safelist to skip irrelevant capabilities during permission checks #543
52
+ * Add helper function `get_guest_author_post_count()` #605
53
+ * Add parameter for outputting HTML classes in `coauthors_get_avatar()` template tag #610
54
+ * Add `--append_coauthors` flag to synopsis of CLI `assign-coauthors` #600
55
+ * Adjust CLI command `create-guest-authors-from-csv` to import website, avatar and description (#603 and #619)
56
+ * Post type of "any" can be used in filters #617
57
+ * Remove unnecessary `is_array()` check #471
58
+ * Remove unnecessary `action_pre_user_query()` #531
59
+ * Use correct args in `search_authors()` #519
60
+ * Have `filter_author_archive_title()` run on author archives only #535
61
+ * Improve tests coverage (#529, #540, #546, #576 and #569)
62
+ * Change `posts_selection` to action from filter #563
63
+ * Fix number of args expected for `get_the_archive_title` callback #657
64
+ * Fix spelling, update FAQ for disabling guest authors and credits in readme (#656, #523 and #501)
65
+ * Output `coauthors_links_single()` template tag correctly when guest author has no website #504
66
+ * Number by "Mine" link shows correct listing of posts #663
67
+ * Linked guest authors show accurate post counts #674
68
+ * Can no longer add co-author more than once #532
69
+ * No more overwriting posts with current user in `add_coauthors()` #545
70
+ * Accurate post count for user when using different login #558
71
+ * No more double post count for users with linked accounts #567
72
+ * Fix SQL error (#593 and #628)
73
+ * Fix "Mine" link href for Pages #547
74
+ * Can delete users when guest authors functionality disabled #602
75
+ * Fix incompatibility issue with Yoast of missing posts in author pages #624
76
+ * Resolve undefined index warnings on author archives #521
77
+ * Resolve warnings when current user has no term assigned #517
78
+
79
+ Props: [TheCrowned](https://github.com/TheCrowned), [shantanu2704](https://github.com/shantanu2704), [WPprodigy](https://github.com/WPprodigy), [blunce24](https://github.com/blunce24), [rebeccahum](https://github.com/rebeccahum), [andrewfleming](https://github.com/andrewfleming), [justnorris](https://github.com/justnorris), [sboisvert](https://github.com/sboisvert), [jasonbahl](https://github.com/jasonbahl), [mariovalney](https://github.com/mariovalney), [RoyTheRoyalBoy](https://github.com/RoyTheRoyalBoy), [jacobarriola](https://github.com/jacobarriola), [smistephen](https://github.com/smistephen), [manzoorwanijk](https://github.com/manzoorwanijk), [kodemonster](https://github.com/kodemonster), [westonruter](https://github.com/westonruter), [binodkalathil](https://github.com/binodkalathil), [scofennell](https://github.com/scofennell), [hyperionjrw](https://github.com/hyperionjrw), [pdemarte](https://github.com/pdemarte), [mostafaabd](https://github.com/mostafaabd), [paulschreiber](https://github.com/paulschreiber)
80
+
81
+ **3.3.1 "Gutentag" (Dec. 7, 2018)**
82
+ * 5.0 Compat: Hide core author inputs when using the Block Editor to limit confusion (h/t jonathanstegall).
83
+
84
+ **3.3.0 "Rebecca" (Apr. 16, 2018)**
85
+ * Fix private post viewing on front-end #386
86
+ * Reduce amount of sleep #400
87
+ * Author search UX issues #407
88
+ * Remove associated guest user when mapped user id deleted. #414
89
+ * Removed double left join on posts_join_filter #419
90
+ * Fixed WP CLI create-terms-for-posts if no co-authors found #420
91
+ * Pages archive now displays co-authors and quick edit works #422
92
+ * Terminology updated throughout #423
93
+ * Replace hardcoded 'author' with $this->$coauthor_taxonomy #426
94
+ * Move parenthesis to fix esc_html and sprintf #430
95
+ * Added progress to create-guest-authors so users have an idea of how long it will take #431
96
+ * Deleting guest authors is less confusing #432
97
+ * Guest author's featured image is avatar now #433
98
+ * Removed extra image sizing #434
99
+ * Remove duplicated byline #435
100
+ * coauthors_wp_list_authors() has option to list only guest authors now #436
101
+ * remove duplicates from linked accounts on coauthors_wp_list_authors() #437
102
+ * Accurate Guest Author post count on linked accounts #438
103
+ * New README.md #439
104
+ * Filter author archive #441
105
+ * Fix coauthors_links_single() #444
106
+ * Added guest author hooks for create/delete #446
107
+ * Fixes logic for DOING_AUTOSAVE check #450
108
+ * user_login spaces problem when using add_coauthors #453
109
+ * Adding details of filter for slow performance #456
110
+ * Remove redundant test for 404 on Author Archive #457
111
+ * Guest Author Counts are more accurate #461
112
+ * Set $coauthors_loading #468
113
+ * Fix the issue where guest authors with non-ASCII characters can't be used as co-authors #473
114
+ * Fix the issue where incompatibility when `coauthors_auto_apply_template_tags` set to true #474
115
+ * Unit tests/Fix warnings for template tags #475
116
+ * Review and improve test coverage #476
117
+ * Update class-wp-cli.php #480
118
+ * Update .travis.yml file for PHPUnit tests #482
119
+ * Changes to resolve issue #332 about missing coauthor meta #484
120
+
121
+ Props to the many people who helped make this release possible: [catchmyfame](https://github.com/catchmyfame), [danielbachhuber](https://github.com/danielbachhuber), [david-binda](https://github.com/david-binda), [douglas-johnson](https://github.com/douglas-johnson), [castlehouse](https://github.com/castlehouse), [frankar](https://github.com/frankar), [haleeben](https://github.com/haleeben), [jjeaton](https://github.com/jjeaton), [johnbillion](https://github.com/johnbillion), [kevinlisota](https://github.com/kevinlisota), [mattoperry](https://github.com/mattoperry), [mdbitz](https://github.com/mdbitz), [mdchiragpatel](https://github.com/mdchiragpatel), [megfh](https://github.com/megfh), [mjangda](https://github.com/mjangda), [mslinnea](https://github.com/mslinnea), [natebot](https://github.com/natebot), [nickdaugherty](https://github.com/nickdaugherty), [nilzari](https://github.com/nilzari), [philipjohn](https://github.com/philipjohn), [pkevan](https://github.com/pkevan), [rebeccahum](https://github.com/rebeccahum), [ryanmarkel](https://github.com/ryanmarkel), [sanketio](https://github.com/sanketio), [sboisvert](https://github.com/sboisvert), [Spongsta](https://github.com/Spongsta), [srguglielmo](https://github.com/srguglielmo), [timburden](https://github.com/timburden), [trepmal](https://github.com/trepmal), [TylerDurdon](https://github.com/TylerDurdon)
122
+
123
+ **3.2.2 (Apr. 3, 2017)**
124
+ * Fix broken author ordering in 4.7+ (props mslinnea)
125
+ * Fix no moderation e-mail bug (props RobjS)
126
+ * Cached functions in CLI commands (props jasonbahl)
127
+ * Fix missing echos (props trepmal)
128
+ * Add `coauthors_guest_author_query_args` filter (props trepmal)
129
+
130
+ **3.2.1 (May 16, 2016)**
131
+ * Hotfix for broken Guest Author bio metabox (props JS Morisset)
132
+
133
+ **3.2 (May 12, 2016)**
134
+ * Various minor bug and security fixes
135
+
136
+ **3.1.2 (Aug. 31, 2015)**
137
+ * Minor bug fixes and coding standards changes.
138
+ * The author's display name is now filtered through `the_author` in `coauthors_posts_links_single()`
139
+ * New Russian and Ukrainian translations, courtesy of [Jurko Chervony](http://skinik.name/).
140
+
141
+ **3.1.1 (Mar. 20, 2014)**
142
+ * Bug fix: Co-authors selection UI should appear when creating a new post too.
143
+
144
+ **3.1 (Mar. 17, 2014)**
145
+ * Manage co-authors from Quick Edit. Props [mpatek](https://github.com/mpatek).
146
+ * Updated Spanish translation, courtesy of [sergiomajluf](https://github.com/sergiomajluf).
147
+ * Now matches core behavior when displaying author archive on multisite: user of the blog, or previously published author on the blog.
148
+ * Breaking change: "Create Profile" link is no longer shown by default on the Manage Users screen. Instead, it can be enabled with the `coauthors_show_create_profile_user_link` filter.
149
+ * Guest authors work properly with Jetpack Open Graph tags. Props [hibernation](https://github.com/hibernation).
150
+ * Guest author profile editor now supports a few different fields. Props [alpha1](https://github.com/alpha1).
151
+ * New `coauthors_count_published_post_types` filter for specifying the post type(s) used when calculating the user's number of published posts.
152
+ * Bug fix: Ensure `post_author` is set to one of the co-authors assigned to a post.
153
+ * Bug fix: Filter author feed link for guest authors on the author page. Props [hibernation](https://github.com/hibernation).
154
+ * Packages a composer.json file for those using Composer.
155
+ * Beginnings of unit test coverage for core features. Increased minimum required WordPress version to 3.7 because WordPress.org unit testing framework doesn't work reliabilty below that.
156
+
157
+ **3.0.7 (Jan. 27, 2014)**
158
+ * Better support for installing Co-Authors Plus as a symlinked directory. [Follow these instructions](http://kaspars.net/blog/wordpress/plugins-via-symlinks) to filter `plugins_url`.
159
+ * Links to authors' posts pages to comply to hCard microformat, which Google depends on.
160
+ * New `coauthors_emails()` template tag to list email addresses of the co-authors. Props [benlk](https://github.com/benlk).
161
+ * Bug fix: Remove extraneous space between last two co-authors output. Props [johnciacia](https://github.com/johnciacia).
162
+ * Updated French translation, courtesy of Jojaba (via email).
163
+
164
+ **3.0.6 (Dec. 9, 2013)**
165
+ * New Swedish translation, courtesy of [alundstroem](https://github.com/alundstroem)
166
+ * Updated German translation, courtesy of [krafit](https://github.com/krafit).
167
+ * New Dutch translation, courtesy of [kardotim](https://github.com/kardotim)
168
+ * New filter for specifying the default author assigned to a post. Props [tannerm](https://github.com/tannerm)
169
+ * Bug fix: When filtering a user's published post count, use the value of their guest author profile if one is mapped.
170
+ * Added support for checkboxes in Guest Author profiles
171
+ * Fix Strict warnings from CPT's that don't define all capabilities
172
+ * New swap-coauthors CLI command for replacing one co-author with another
173
+
174
+ **3.0.5 (Feb. 18, 2013)**
175
+ * New filter `coauthors_search_authors_get_terms_args` allows you to increase the number of matches returned with AJAX co-author selection
176
+ * Bug fix: If there isn't an author term yet for a co-author, avoid an erronous join that caused duplicate posts to appear.
177
+
178
+ **3.0.4 (Jan. 6, 2013)** =
179
+ * Support for automatically adding co-authors to your feeds. Props [cfg](https://github.com/cfg).
180
+ * Bug fix: No Co-Authors Plus on attachments. For now.
181
+ * Bug fix: Better support for co-authors with non-standard user_nicenames. Props [STRML](https://github.com/STRML).
182
+
183
+ **3.0.3 (Dec. 3, 2012)**
184
+ * Bug fix: The default order for the 'author' taxonomy should be `term_order`, in order for the author positions to stick. Props [lgedeon](https://github.com/lgedeon)
185
+
186
+ **3.0.2 (Nov. 23, 2012)**
187
+ * Bug fix: Fall back to non-pretty permalinks when the author permastruct is empty, so that `coauthors_posts_links()` doesn't link to the homepage
188
+
189
+ **3.0.1 (Nov. 21, 2012)**
190
+ * Add your own custom columns to the guest authors table using filters. Props [cfg](https://github.com/cfg)
191
+ * A new wp-cli subcommand for renaming co-authors and another for removing author terms mistakenly assigned to revisions
192
+ * Bug fix: Using a featured image for a guest author avatar didn't work. Now it does.
193
+ * Bug fix: Don't assign author terms to revisions to avoid unnecessary database bloat
194
+ * Bug fix: Make the `coauthors_wp_list_authors()` template tag work again
195
+ * Bug fix: Improve capability filtering by properly handling super admin access and situations where `user_id = 0`
196
+ * Minor UI enhancements for guest authors
197
+
198
+ **3.0 (Nov. 12, 2012)**
199
+ * Create guest author profiles for bylines you'd like to assign without creating WordPress user accounts. Guest authors can have all of the same fields as normal users including display name, biography, and avatars.
200
+ * Support for non-Latin characters in usernames and guest author names
201
+ * wp-cli subcommands for creating, assigning, and reassigning co-authors
202
+ * For themes using core template tags like `the_author()` or `the_author_posts_link()`, you enable Co-Authors Plus support with a simple filter
203
+ * New author terms are now prefixed with `cap-` to avoid collisions with global scope
204
+ * Bug fix: Apply query filters to only `post_types` registered with the taxonomy. Props [Tom Ransom](https://github.com/1bigidea)
205
+ * Filter `coauthors_posts_link_single()` with `coauthors_posts_link`. Also adds `rel="author"`. Props [Amit Sannad](https://github.com/asannad) and [Gabriel Koen](https://github.com/mintindeed)
206
+ * Filter for the context and priorities of the Co-Authors meta boxes. Props [Tomáš Kapler](https://github.com/tkapler)
207
+ * Renamed the post meta box for selecting authors so it applies to many post types. Props [John Blackbourn](https://github.com/johnbillion)
208
+
209
+ **2.6.4 (May 7, 2012)**
210
+ * Bug fix: Properly filter the user query so users can AJAX search against the display name field again
211
+ * If https is used for the admin, also use the secure Gravatar URL. Props [rmcfrazier](https://github.com/rmcfrazier)
212
+
213
+ **2.6.3 (Apr. 30, 2012)**
214
+ * AJAX user search is back to searching against user login, display name, email address and user ID. The method introduced in v2.6.2 didn't scale well
215
+ * French translation courtesy of Sylvain Bérubé
216
+ * Spanish translation courtesy of Alejandro Arcos
217
+ * Bug fix: Resolved incorrect caps check against user editing an already published post. [See forum thread](http://wordpress.org/support/topic/multiple-authors-cant-edit-pages?replies=17#post-2741243)
218
+
219
+ **2.6.2 (Mar. 6, 2012)**
220
+ * AJAX user search matches against first name, last name, and nickname fields too, in addition to display name, user login, and email address
221
+ * Comment moderation and approved notifications are properly sent to all co-authors with the correct caps
222
+ * Filter required capability for user to be returned in an AJAX search with `coauthors_edit_author_cap`
223
+ * Filter out administrators and other non-authors from AJAX search with `coauthors_edit_ignored_authors`
224
+ * Automatically adds co-authors to Edit Flow's story budget and calendar views
225
+ * Bug fix: Don't set post_author value to current user when quick editing a post. This doesn't appear in the UI anywhere, but adds the post to the current user's list of posts
226
+ * Bug fix: Properly cc other co-authors on new comment email notifications
227
+ * Bug fix: If a user has already been added as an author to a post, don't show them in the AJAX search again
228
+ * Bug fix: Allow output constants to be defined in a theme's functions.php file and include filters you can use instead
229
+
230
+ **2.6.1 (Dec. 30, 2011)**
231
+ * Fix mangled usernames because of sanitize_key http://wordpress.org/support/topic/plugin-co-authors-plus-26-not-working-with-wp-33
232
+
233
+ **2.6 (Dec. 22, 2011)**
234
+ * Sortable authors: Drag and drop the order of the authors as you'd like them to appear ([props kingkool68](http://profiles.wordpress.org/users/kingkool68/))
235
+ * Search for authors by display name (instead of nicename which was essentially the same as user_login)
236
+ * Option to remove the first author when there are two or more so it's less confusing
237
+ * Bumped requirements to WordPress 3.1
238
+ * Bug fix: Update the published post count for each user more reliably
239
+
240
+ **2.5.3 (Aug. 14, 2011)**
241
+ * Bug fix: Removed extra comma when only two authors were listed. If you used the `COAUTHORS_DEFAULT_BETWEEN_LAST` constant, double-check what you have
242
+
243
+ **2.5.2 (Apr. 23, 2011)**
244
+ * Bug: Couldn't query terms and authors at the same time (props nbaxley)
245
+ * Bug: Authors with empty fields (e.g. first name) were displaying blank in some cases
246
+ * Bug: authors with spaces in usernames not getting saved (props MLmsw, Ruben S. and others!)
247
+ * Bug: revisions getting wrong user attached (props cliquenoir!)
248
+
249
+ **2.5.1 (Mar. 26, 2011)**
250
+ * Fix with author post count (throwing errors)
251
+
252
+ **2.5 (Mar. 26, 2011)**
253
+ * Custom Post Type Support
254
+ * Compatibility with WP 3.0 and 3.1
255
+ * Gravatars
256
+ * Lots and lots and lots of bug fixes
257
+ * Thanks to everyone who submitted bugs, fixes, and suggestions! And for your patience!
258
+
259
+ **2.1.1 (Oct. 16, 2009)**
260
+ * Fix for co-authors not being added if their username is different from display name
261
+ * Fixes to readme.txt (fixes for textual and punctuation errors, language clarification, minor formatting changes) courtesy of [Waldo Jaquith](http://www.vqronline.org)
262
+
263
+ **2.1 (Oct. 11, 2009)**
264
+ * Fixed issues related to localization. Thanks to Jan Zombik <zombik@students.uni-mainz.de> for the fixes.
265
+ * Added `set_time_limit` to update function to get around timeout issues when upgrading plugin
266
+
267
+ **2.0 (Oct. 11, 2009)**
268
+ * Plugin mostly rewritten to make use of taxonomy instead of `post_meta`
269
+ * Can now see all authors of a post under the author column from Edit Posts page
270
+ * All authors of a post are now notified on a new comment
271
+ * Various javascript enhancements
272
+ * New option to allow subscribers to be added as authors
273
+ * All Authors can edit they posts of which they are co-authors
274
+ * FIX: Issues with `wp_coauthors_list` function
275
+ * FIX: Issues with coauthored posts not showing up on author archives
276
+
277
+ **1.2.0 (Jun. 16, 2012)**
278
+ * FIX: Added compatibility for WordPress 2.8
279
+ * 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.
280
+ * FIX: Plugin should now work for plugins not using the `wp_` DB prefix
281
+ * FIX: Coauthors should no longer be alphabetically reordered when the post is updated
282
+ * FIX: Plugin now used WordPress native AJAX calls to tighten security
283
+ * DOCS: Added details about the new template tags
284
+
285
+ **1.1.5 (Apr. 26, 2009)**
286
+ * FIX: Not searching Updated SQL query for autosuggest to search through first name, last name, and nickname
287
+ * FIX: When editing an author, and clicking on a suggested author, the original author was not be removed
288
+ * DOCS: Added code comments to javascript; more still to be added
289
+ * DOCS: Updated readme information
290
+
291
+ **1.1.4 (Apr. 25, 2009)**
292
+ * Disabled "New Author" output in suggest box, for now
293
+ * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
294
+
295
+ **1.1.3 (Apr. 23, 2009)**
296
+ * Add blur event to disable input box
297
+ * Limit only one edit at a time.
298
+ * Checked basic cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
299
+ * Add suggest javascript plugin to Edit Page.
300
+
301
+ **1.1.2 (Apr. 19, 2009)**
302
+ * Disabled form submit when enter pressed.
303
+
304
+ **1.1.1 (Apr. 15, 2009)**
305
+ * Changed SQL query to return only contributor-level and above users.
306
+
307
+ **1.1.0 (Apr. 14, 2009)**
308
+ * Initial beta release.
README.md CHANGED
@@ -4,7 +4,7 @@
4
  * Tags: authors, users, multiple authors, co-authors, multi-author, publishing
5
  * Tested up to: 5.7
6
  * Requires at least: 4.1
7
- * Stable tag: 3.4.5
8
 
9
  Assign multiple bylines to posts, pages, and custom post types via a search-as-you-type input box
10
 
@@ -69,299 +69,6 @@ add_filter( 'coauthors_count_published_post_types', function( $post_types ) {
69
  ```
70
  2. To display the metabox on your CPT, either call `register_post_type()` with `$args['supports']` containing `'author'`, or call `add_post_type_support( 'my_cpt_slug', 'author' );`
71
 
72
- ## Changelog ##
73
-
74
- **3.4.5**
75
- * Fixed bug where guest authors with spaces in names were not showing when queried in AJAX suggest box.
76
-
77
- **3.4.4**
78
- * Fixed bug where author with slug beginning with "cap" does not appear in bylines AJAX suggest box when queried #744
79
- * Travis for Xenial build no longer fails #751
80
- * Unit tests no longer fail #752
81
- * Fixed REST permissions bug where co-author cannot view post assigned to them in Gutenberg #757
82
-
83
- **3.4.3**
84
- * Added author support to CPT instructions in readme FAQ #720
85
- * Added object check for user in `coauthors_set_post_author_field()` #721
86
- * Fix inefficient user query in avatar url hook #724
87
- * Fix operand typo in `get_guest_author_thumbnail()` for adding custom classes #725
88
- * Remove hardcoded default avatar and use default option #728
89
-
90
- **3.4.2**
91
- * Fix incorrect user avatar being displayed from featured post image #706
92
- * Add check for `filter_get_avatar_url` to ensure valid second parameter #707
93
- * `add_coauthors()` accepts ID parameter now #685 and ensures valid term slug used #708
94
- * `filter_count_user_posts` checks that user ID returns valid user object #714
95
- * Added post count instructions in readme FAQ for CPTs #713
96
-
97
- **3.4.1**
98
- * Fix an issue that may arise in bulk edit #700
99
-
100
- **3.4**
101
- * New filter `get_coauthors` for modifying coauthor data returned in `get_coauthors()` #646
102
- * New filter `coauthors_guest_authors_exported_extra_data` to allow guest author to export data as regular author #528
103
- * New filter `get_avatar_url()` to show avatar in JS selection #621
104
- * New parameter in `coauthors_wp_list_authors()` to only query authors with posts #496
105
- * Add internationalization support to title and name in author archives #516
106
- * Add safelist to skip irrelevant capabilities during permission checks #543
107
- * Add helper function `get_guest_author_post_count()` #605
108
- * Add parameter for outputting HTML classes in `coauthors_get_avatar()` template tag #610
109
- * Add `--append_coauthors` flag to synopsis of CLI `assign-coauthors` #600
110
- * Adjust CLI command `create-guest-authors-from-csv` to import website, avatar and description (#603 and #619)
111
- * Post type of "any" can be used in filters #617
112
- * Remove unnecessary `is_array()` check #471
113
- * Remove unnecessary `action_pre_user_query()` #531
114
- * Use correct args in `search_authors()` #519
115
- * Have `filter_author_archive_title()` run on author archives only #535
116
- * Improve tests coverage (#529, #540, #546, #576 and #569)
117
- * Change `posts_selection` to action from filter #563
118
- * Fix number of args expected for `get_the_archive_title` callback #657
119
- * Fix spelling, update FAQ for disabling guest authors and credits in readme (#656, #523 and #501)
120
- * Output `coauthors_links_single()` template tag correctly when guest author has no website #504
121
- * Number by "Mine" link shows correct listing of posts #663
122
- * Linked guest authors show accurate post counts #674
123
- * Can no longer add co-author more than once #532
124
- * No more overwriting posts with current user in `add_coauthors()` #545
125
- * Accurate post count for user when using different login #558
126
- * No more double post count for users with linked accounts #567
127
- * Fix SQL error (#593 and #628)
128
- * Fix "Mine" link href for Pages #547
129
- * Can delete users when guest authors functionality disabled #602
130
- * Fix incompatibility issue with Yoast of missing posts in author pages #624
131
- * Resolve undefined index warnings on author archives #521
132
- * Resolve warnings when current user has no term assigned #517
133
-
134
- Props: [TheCrowned](https://github.com/TheCrowned), [shantanu2704](https://github.com/shantanu2704), [WPprodigy](https://github.com/WPprodigy), [blunce24](https://github.com/blunce24), [rebeccahum](https://github.com/rebeccahum), [andrewfleming](https://github.com/andrewfleming), [justnorris](https://github.com/justnorris), [sboisvert](https://github.com/sboisvert), [jasonbahl](https://github.com/jasonbahl), [mariovalney](https://github.com/mariovalney), [RoyTheRoyalBoy](https://github.com/RoyTheRoyalBoy), [jacobarriola](https://github.com/jacobarriola), [smistephen](https://github.com/smistephen), [manzoorwanijk](https://github.com/manzoorwanijk), [kodemonster](https://github.com/kodemonster), [westonruter](https://github.com/westonruter), [binodkalathil](https://github.com/binodkalathil), [scofennell](https://github.com/scofennell), [hyperionjrw](https://github.com/hyperionjrw), [pdemarte](https://github.com/pdemarte), [mostafaabd](https://github.com/mostafaabd), [paulschreiber](https://github.com/paulschreiber)
135
-
136
- **3.3.1 ("Gutentag")**
137
- * 5.0 Compat: Hide core author inputs when using the Block Editor to limit confusion (h/t jonathanstegall).
138
-
139
- **3.3.0 ("Rebecca")**
140
- * Fix private post viewing on front-end #386
141
- * Reduce amount of sleep #400
142
- * Author search UX issues #407
143
- * Remove associated guest user when mapped user id deleted. #414
144
- * Removed double left join on posts_join_filter #419
145
- * Fixed WP CLI create-terms-for-posts if no co-authors found #420
146
- * Pages archive now displays co-authors and quick edit works #422
147
- * Terminology updated throughout #423
148
- * Replace hardcoded 'author' with $this->$coauthor_taxonomy #426
149
- * Move parenthesis to fix esc_html and sprintf #430
150
- * Added progress to create-guest-authors so users have an idea of how long it will take #431
151
- * Deleting guest authors is less confusing #432
152
- * Guest author's featured image is avatar now #433
153
- * Removed extra image sizing #434
154
- * Remove duplicated byline #435
155
- * coauthors_wp_list_authors() has option to list only guest authors now #436
156
- * remove duplicates from linked accounts on coauthors_wp_list_authors() #437
157
- * Accurate Guest Author post count on linked accounts #438
158
- * New README.md #439
159
- * Filter author archive #441
160
- * Fix coauthors_links_single() #444
161
- * Added guest author hooks for create/delete #446
162
- * Fixes logic for DOING_AUTOSAVE check #450
163
- * user_login spaces problem when using add_coauthors #453
164
- * Adding details of filter for slow performance #456
165
- * Remove redundant test for 404 on Author Archive #457
166
- * Guest Author Counts are more accurate #461
167
- * Set $coauthors_loading #468
168
- * Fix the issue where guest authors with non-ASCII characters can't be used as co-authors #473
169
- * Fix the issue where incompatibility when `coauthors_auto_apply_template_tags` set to true #474
170
- * Unit tests/Fix warnings for template tags #475
171
- * Review and improve test coverage #476
172
- * Update class-wp-cli.php #480
173
- * Update .travis.yml file for PHPUnit tests #482
174
- * Changes to resolve issue #332 about missing coauthor meta #484
175
-
176
- Props to the many people who helped make this release possible: [catchmyfame](https://github.com/catchmyfame), [danielbachhuber](https://github.com/danielbachhuber), [david-binda](https://github.com/david-binda), [douglas-johnson](https://github.com/douglas-johnson), [castlehouse](https://github.com/castlehouse), [frankar](https://github.com/frankar), [haleeben](https://github.com/haleeben), [jjeaton](https://github.com/jjeaton), [johnbillion](https://github.com/johnbillion), [kevinlisota](https://github.com/kevinlisota), [mattoperry](https://github.com/mattoperry), [mdbitz](https://github.com/mdbitz), [mdchiragpatel](https://github.com/mdchiragpatel), [megfh](https://github.com/megfh), [mjangda](https://github.com/mjangda), [mslinnea](https://github.com/mslinnea), [natebot](https://github.com/natebot), [nickdaugherty](https://github.com/nickdaugherty), [nilzari](https://github.com/nilzari), [philipjohn](https://github.com/philipjohn), [pkevan](https://github.com/pkevan), [rebeccahum](https://github.com/rebeccahum), [ryanmarkel](https://github.com/ryanmarkel), [sanketio](https://github.com/sanketio), [sboisvert](https://github.com/sboisvert), [Spongsta](https://github.com/Spongsta), [srguglielmo](https://github.com/srguglielmo), [timburden](https://github.com/timburden), [trepmal](https://github.com/trepmal), [TylerDurdon](https://github.com/TylerDurdon)
177
-
178
- **3.2.2**
179
- * Fix broken author ordering in 4.7+ (props mslinnea)
180
- * Fix no moderation e-mail bug (props RobjS)
181
- * Cached functions in CLI commands (props jasonbahl)
182
- * Fix missing echos (props trepmal)
183
- * Add `coauthors_guest_author_query_args` filter (props trepmal)
184
-
185
- **3.2.1 (May 16, 2016)**
186
- * Hotfix for broken Guest Author bio metabox (props JS Morisset)
187
-
188
- **3.2 (May 12, 2016)**
189
- * Various minor bug and security fixes
190
-
191
- **3.1.2 (Aug. 31, 2015)**
192
- * Minor bug fixes and coding standards changes.
193
- * The author's display name is now filtered through `the_author` in `coauthors_posts_links_single()`
194
- * New Russian and Ukrainian translations, courtesy of [Jurko Chervony](http://skinik.name/).
195
-
196
- **3.1.1 (Mar. 20, 2014)**
197
- * Bug fix: Co-authors selection UI should appear when creating a new post too.
198
-
199
- **3.1 (Mar. 17, 2014)**
200
- * Manage co-authors from Quick Edit. Props [mpatek](https://github.com/mpatek).
201
- * Updated Spanish translation, courtesy of [sergiomajluf](https://github.com/sergiomajluf).
202
- * Now matches core behavior when displaying author archive on multisite: user of the blog, or previously published author on the blog.
203
- * Breaking change: "Create Profile" link is no longer shown by default on the Manage Users screen. Instead, it can be enabled with the `coauthors_show_create_profile_user_link` filter.
204
- * Guest authors work properly with Jetpack Open Graph tags. Props [hibernation](https://github.com/hibernation).
205
- * Guest author profile editor now supports a few different fields. Props [alpha1](https://github.com/alpha1).
206
- * New `coauthors_count_published_post_types` filter for specifying the post type(s) used when calculating the user's number of published posts.
207
- * Bug fix: Ensure `post_author` is set to one of the co-authors assigned to a post.
208
- * Bug fix: Filter author feed link for guest authors on the author page. Props [hibernation](https://github.com/hibernation).
209
- * Packages a composer.json file for those using Composer.
210
- * Beginnings of unit test coverage for core features. Increased minimum required WordPress version to 3.7 because WordPress.org unit testing framework doesn't work reliabilty below that.
211
-
212
- **3.0.7 (Jan. 27, 2014)**
213
- * Better support for installing Co-Authors Plus as a symlinked directory. [Follow these instructions](http://kaspars.net/blog/wordpress/plugins-via-symlinks) to filter `plugins_url`.
214
- * Links to authors' posts pages to comply to hCard microformat, which Google depends on.
215
- * New `coauthors_emails()` template tag to list email addresses of the co-authors. Props [benlk](https://github.com/benlk).
216
- * Bug fix: Remove extraneous space between last two co-authors output. Props [johnciacia](https://github.com/johnciacia).
217
- * Updated French translation, courtesy of Jojaba (via email).
218
-
219
- **3.0.6 (Dec. 9, 2013)**
220
- * New Swedish translation, courtesy of [alundstroem](https://github.com/alundstroem)
221
- * Updated German translation, courtesy of [krafit](https://github.com/krafit).
222
- * New Dutch translation, courtesy of [kardotim](https://github.com/kardotim)
223
- * New filter for specifying the default author assigned to a post. Props [tannerm](https://github.com/tannerm)
224
- * Bug fix: When filtering a user's published post count, use the value of their guest author profile if one is mapped.
225
- * Added support for checkboxes in Guest Author profiles
226
- * Fix Strict warnings from CPT's that don't define all capabilities
227
- * New swap-coauthors CLI command for replacing one co-author with another
228
-
229
- **3.0.5 (Feb. 18, 2013)**
230
- * New filter `coauthors_search_authors_get_terms_args` allows you to increase the number of matches returned with AJAX co-author selection
231
- * Bug fix: If there isn't an author term yet for a co-author, avoid an erronous join that caused duplicate posts to appear.
232
-
233
- **3.0.4 (Jan. 6, 2013)** =
234
- * Support for automatically adding co-authors to your feeds. Props [cfg](https://github.com/cfg).
235
- * Bug fix: No Co-Authors Plus on attachments. For now.
236
- * Bug fix: Better support for co-authors with non-standard user_nicenames. Props [STRML](https://github.com/STRML).
237
-
238
- **3.0.3 (Dec. 3, 2012)**
239
- * Bug fix: The default order for the 'author' taxonomy should be `term_order`, in order for the author positions to stick. Props [lgedeon](https://github.com/lgedeon)
240
-
241
- **3.0.2 (Nov. 23, 2012)**
242
- * Bug fix: Fall back to non-pretty permalinks when the author permastruct is empty, so that `coauthors_posts_links()` doesn't link to the homepage
243
-
244
- **3.0.1 (Nov. 21, 2012)**
245
- * Add your own custom columns to the guest authors table using filters. Props [cfg](https://github.com/cfg)
246
- * A new wp-cli subcommand for renaming co-authors and another for removing author terms mistakenly assigned to revisions
247
- * Bug fix: Using a featured image for a guest author avatar didn't work. Now it does.
248
- * Bug fix: Don't assign author terms to revisions to avoid unnecessary database bloat
249
- * Bug fix: Make the `coauthors_wp_list_authors()` template tag work again
250
- * Bug fix: Improve capability filtering by properly handling super admin access and situations where `user_id = 0`
251
- * Minor UI enhancements for guest authors
252
-
253
- **3.0 (Nov. 12, 2012)**
254
- * Create guest author profiles for bylines you'd like to assign without creating WordPress user accounts. Guest authors can have all of the same fields as normal users including display name, biography, and avatars.
255
- * Support for non-Latin characters in usernames and guest author names
256
- * wp-cli subcommands for creating, assigning, and reassigning co-authors
257
- * For themes using core template tags like `the_author()` or `the_author_posts_link()`, you enable Co-Authors Plus support with a simple filter
258
- * New author terms are now prefixed with `cap-` to avoid collisions with global scope
259
- * Bug fix: Apply query filters to only `post_types` registered with the taxonomy. Props [Tom Ransom](https://github.com/1bigidea)
260
- * Filter `coauthors_posts_link_single()` with `coauthors_posts_link`. Also adds `rel="author"`. Props [Amit Sannad](https://github.com/asannad) and [Gabriel Koen](https://github.com/mintindeed)
261
- * Filter for the context and priorities of the Co-Authors meta boxes. Props [Tomáš Kapler](https://github.com/tkapler)
262
- * Renamed the post meta box for selecting authors so it applies to many post types. Props [John Blackbourn](https://github.com/johnbillion)
263
-
264
- **2.6.4 (May 7, 2012)**
265
- * Bug fix: Properly filter the user query so users can AJAX search against the display name field again
266
- * If https is used for the admin, also use the secure Gravatar URL. Props [rmcfrazier](https://github.com/rmcfrazier)
267
-
268
- **2.6.3 (Apr. 30, 2012)**
269
- * AJAX user search is back to searching against user login, display name, email address and user ID. The method introduced in v2.6.2 didn't scale well
270
- * French translation courtesy of Sylvain Bérubé
271
- * Spanish translation courtesy of Alejandro Arcos
272
- * Bug fix: Resolved incorrect caps check against user editing an already published post. [See forum thread](http://wordpress.org/support/topic/multiple-authors-cant-edit-pages?replies=17#post-2741243)
273
-
274
- **2.6.2 (Mar. 6, 2012)**
275
- * AJAX user search matches against first name, last name, and nickname fields too, in addition to display name, user login, and email address
276
- * Comment moderation and approved notifications are properly sent to all co-authors with the correct caps
277
- * Filter required capability for user to be returned in an AJAX search with `coauthors_edit_author_cap`
278
- * Filter out administrators and other non-authors from AJAX search with `coauthors_edit_ignored_authors`
279
- * Automatically adds co-authors to Edit Flow's story budget and calendar views
280
- * Bug fix: Don't set post_author value to current user when quick editing a post. This doesn't appear in the UI anywhere, but adds the post to the current user's list of posts
281
- * Bug fix: Properly cc other co-authors on new comment email notifications
282
- * Bug fix: If a user has already been added as an author to a post, don't show them in the AJAX search again
283
- * Bug fix: Allow output constants to be defined in a theme's functions.php file and include filters you can use instead
284
-
285
- **2.6.1 (Dec. 30, 2011)**
286
- * Fix mangled usernames because of sanitize_key http://wordpress.org/support/topic/plugin-co-authors-plus-26-not-working-with-wp-33
287
-
288
- **2.6 (Dec. 22, 2011)**
289
- * Sortable authors: Drag and drop the order of the authors as you'd like them to appear ([props kingkool68](http://profiles.wordpress.org/users/kingkool68/))
290
- * Search for authors by display name (instead of nicename which was essentially the same as user_login)
291
- * Option to remove the first author when there are two or more so it's less confusing
292
- * Bumped requirements to WordPress 3.1
293
- * Bug fix: Update the published post count for each user more reliably
294
-
295
- **2.5.3 (Aug. 14, 2011)**
296
- * Bug fix: Removed extra comma when only two authors were listed. If you used the `COAUTHORS_DEFAULT_BETWEEN_LAST` constant, double-check what you have
297
-
298
- **2.5.2 (Apr. 23, 2011)**
299
- * Bug: Couldn't query terms and authors at the same time (props nbaxley)
300
- * Bug: Authors with empty fields (e.g. first name) were displaying blank in some cases
301
- * Bug: authors with spaces in usernames not getting saved (props MLmsw, Ruben S. and others!)
302
- * Bug: revisions getting wrong user attached (props cliquenoir!)
303
-
304
- **2.5.1 (Mar. 26, 2011)**
305
- * Fix with author post count (throwing errors)
306
-
307
- **2.5 (Mar. 26, 2011)**
308
- * Custom Post Type Support
309
- * Compatibility with WP 3.0 and 3.1
310
- * Gravatars
311
- * Lots and lots and lots of bug fixes
312
- * Thanks to everyone who submitted bugs, fixes, and suggestions! And for your patience!
313
-
314
- **2.1.1 (Oct. 16, 2009)**
315
- * Fix for co-authors not being added if their username is different from display name
316
- * Fixes to readme.txt (fixes for textual and punctuation errors, language clarification, minor formatting changes) courtesy of [Waldo Jaquith](http://www.vqronline.org)
317
-
318
- **2.1 (Oct. 11, 2009)**
319
- * Fixed issues related to localization. Thanks to Jan Zombik <zombik@students.uni-mainz.de> for the fixes.
320
- * Added `set_time_limit` to update function to get around timeout issues when upgrading plugin
321
-
322
- **2.0 (Oct. 11, 2009)**
323
- * Plugin mostly rewritten to make use of taxonomy instead of `post_meta`
324
- * Can now see all authors of a post under the author column from Edit Posts page
325
- * All authors of a post are now notified on a new comment
326
- * Various javascript enhancements
327
- * New option to allow subscribers to be added as authors
328
- * All Authors can edit they posts of which they are co-authors
329
- * FIX: Issues with `wp_coauthors_list` function
330
- * FIX: Issues with coauthored posts not showing up on author archives
331
-
332
- **1.2.0 (Jun. 16, 2012)**
333
- * FIX: Added compatibility for WordPress 2.8
334
- * 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.
335
- * FIX: Plugin should now work for plugins not using the `wp_` DB prefix
336
- * FIX: Coauthors should no longer be alphabetically reordered when the post is updated
337
- * FIX: Plugin now used WordPress native AJAX calls to tighten security
338
- * DOCS: Added details about the new template tags
339
-
340
- **1.1.5 (Apr. 26, 2009)**
341
- * FIX: Not searching Updated SQL query for autosuggest to search through first name, last name, and nickname
342
- * FIX: When editing an author, and clicking on a suggested author, the original author was not be removed
343
- * DOCS: Added code comments to javascript; more still to be added
344
- * DOCS: Updated readme information
345
-
346
- **1.1.4 (Apr. 25, 2009)**
347
- * Disabled "New Author" output in suggest box, for now
348
- * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
349
-
350
- **1.1.3 (Apr. 23, 2009)**
351
- * Add blur event to disable input box
352
- * Limit only one edit at a time.
353
- * Checked basic cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
354
- * Add suggest javascript plugin to Edit Page.
355
-
356
- **1.1.2 (Apr. 19, 2009)**
357
- * Disabled form submit when enter pressed.
358
-
359
- **1.1.1 (Apr. 15, 2009)**
360
- * Changed SQL query to return only contributor-level and above users.
361
-
362
- **1.1.0 (Apr. 14, 2009)**
363
- * Initial beta release.
364
-
365
  ## Installation
366
 
367
  1. IMPORTANT: Please disable the original Co-Authors plugin (if you are using it) before installing Co-Authors Plus
4
  * Tags: authors, users, multiple authors, co-authors, multi-author, publishing
5
  * Tested up to: 5.7
6
  * Requires at least: 4.1
7
+ * Stable tag: 3.4.6
8
 
9
  Assign multiple bylines to posts, pages, and custom post types via a search-as-you-type input box
10
 
69
  ```
70
  2. To display the metabox on your CPT, either call `register_post_type()` with `$args['supports']` containing `'author'`, or call `add_post_type_support( 'my_cpt_slug', 'author' );`
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  ## Installation
73
 
74
  1. IMPORTANT: Please disable the original Co-Authors plugin (if you are using it) before installing Co-Authors Plus
co-authors-plus.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Co-Authors Plus
4
  Plugin URI: http://wordpress.org/extend/plugins/co-authors-plus/
5
  Description: Allows multiple authors to be assigned to a post. This plugin is an extended version of the Co-Authors plugin developed by Weston Ruter.
6
- Version: 3.4.5
7
  Author: Mohammad Jangda, Daniel Bachhuber, Automattic
8
  Copyright: 2008-2015 Shared and distributed between Mohammad Jangda, Daniel Bachhuber, Weston Ruter
9
 
@@ -32,16 +32,16 @@ Co-author - in the context of a single post, a guest author or user assigned to
32
  Author - user with the role of author
33
  */
34
 
35
- define( 'COAUTHORS_PLUS_VERSION', '3.4.5' );
36
 
37
- require_once( dirname( __FILE__ ) . '/template-tags.php' );
38
- require_once( dirname( __FILE__ ) . '/deprecated.php' );
39
 
40
- require_once( dirname( __FILE__ ) . '/php/class-coauthors-template-filters.php' );
41
- require_once( dirname( __FILE__ ) . '/php/integrations/amp.php' );
42
 
43
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
44
- require_once( dirname( __FILE__ ) . '/php/class-wp-cli.php' );
45
  }
46
 
47
  class CoAuthors_Plus {
@@ -51,8 +51,8 @@ class CoAuthors_Plus {
51
  var $coauthor_taxonomy = 'author';
52
 
53
  var $coreauthors_meta_box_name = 'authordiv';
54
- var $coauthors_meta_box_name = 'coauthorsdiv';
55
- var $force_guest_authors = false;
56
 
57
  var $gravatar_size = 25;
58
 
@@ -89,7 +89,7 @@ class CoAuthors_Plus {
89
  add_filter( 'wp_insert_post_data', array( $this, 'coauthors_set_post_author_field' ), 10, 2 );
90
 
91
  // Action to reassign posts when a guest author is deleted
92
- add_action( 'delete_user', array( $this, 'delete_user_action' ) );
93
 
94
  add_filter( 'get_usernumposts', array( $this, 'filter_count_user_posts' ), 10, 2 );
95
 
@@ -127,12 +127,12 @@ class CoAuthors_Plus {
127
  add_filter( 'infinite_scroll_js_settings', array( $this, 'filter_infinite_scroll_js_settings' ), 10, 2 );
128
 
129
  // Delete Co-Author Cache on Post Save & Post Delete
130
- add_action( 'save_post', array( $this, 'clear_cache') );
131
- add_action( 'delete_post', array( $this, 'clear_cache') );
132
  add_action( 'set_object_terms', array( $this, 'clear_cache_on_terms_set' ), 10, 6 );
133
 
134
  // Filter to correct author on author archive page
135
- add_filter( 'get_the_archive_title', array( $this, 'filter_author_archive_title'), 10, 1 );
136
 
137
  // Filter to display author image if exists instead of avatar
138
  add_filter( 'pre_get_avatar_data', array( $this, 'filter_pre_get_avatar_data_url' ), 10, 2 );
@@ -149,8 +149,8 @@ class CoAuthors_Plus {
149
 
150
  // Load the Guest Authors functionality if needed
151
  if ( $this->is_guest_authors_enabled() ) {
152
- require_once( dirname( __FILE__ ) . '/php/class-coauthors-guest-authors.php' );
153
- $this->guest_authors = new CoAuthors_Guest_Authors;
154
  if ( apply_filters( 'coauthors_guest_authors_force', false ) ) {
155
  $this->force_guest_authors = true;
156
  }
@@ -159,7 +159,7 @@ class CoAuthors_Plus {
159
  // Maybe automatically apply our template tags
160
  if ( apply_filters( 'coauthors_auto_apply_template_tags', false ) ) {
161
  global $coauthors_plus_template_filters;
162
- $coauthors_plus_template_filters = new CoAuthors_Template_Filters;
163
  }
164
 
165
  }
@@ -172,13 +172,13 @@ class CoAuthors_Plus {
172
  // Register new taxonomy so that we can store all of the relationships
173
  $args = array(
174
  'hierarchical' => false,
175
- 'label' => false,
176
- 'query_var' => false,
177
- 'rewrite' => false,
178
- 'public' => false,
179
- 'sort' => true,
180
- 'args' => array( 'orderby' => 'term_order' ),
181
- 'show_ui' => false,
182
  );
183
 
184
  // If we use the nasty SQL query, we need our custom callback. Otherwise, we still need to flush cache.
@@ -272,11 +272,12 @@ class CoAuthors_Plus {
272
  if ( 'user_nicename' == $key ) {
273
  $key = 'slug';
274
  }
275
- // Ensure we aren't doing the lookup by the prefixed value
276
- if ( 'login' == $key || 'slug' == $key ) {
 
277
  $value = preg_replace( '#^cap\-#', '', $value );
 
278
  }
279
- $user = get_user_by( $key, $value );
280
  if ( ! $user ) {
281
  return false;
282
  }
@@ -309,7 +310,7 @@ class CoAuthors_Plus {
309
 
310
  if ( ! $post_type ) {
311
  $post_type = get_post_type();
312
- if ( is_admin() && ! $post_type) {
313
  $post_type = get_current_screen()->post_type;
314
  }
315
  }
@@ -463,19 +464,19 @@ class CoAuthors_Plus {
463
  $count = 1;
464
  foreach ( $authors as $author ) :
465
  $args = array(
466
- 'author_name' => $author->user_nicename,
467
- );
468
  if ( 'post' != $post->post_type ) {
469
  $args['post_type'] = $post->post_type;
470
  }
471
  $author_filter_url = add_query_arg( array_map( 'rawurlencode', $args ), admin_url( 'edit.php' ) );
472
  ?>
473
  <a href="<?php echo esc_url( $author_filter_url ); ?>"
474
- data-user_nicename="<?php echo esc_attr( $author->user_nicename ) ?>"
475
- data-user_email="<?php echo esc_attr( $author->user_email ) ?>"
476
- data-display_name="<?php echo esc_attr( $author->display_name ) ?>"
477
- data-user_login="<?php echo esc_attr( $author->user_login ) ?>"
478
- data-avatar="<?php echo esc_attr( get_avatar_url( $author->ID ) ) ?>"
479
  ><?php echo esc_html( $author->display_name ); ?></a><?php echo ( $count < count( $authors ) ) ? ',' : ''; ?>
480
  <?php
481
  $count++;
@@ -508,8 +509,8 @@ class CoAuthors_Plus {
508
  return $value;
509
  }
510
  // We filter count_user_posts() so it provides an accurate number
511
- $numposts = count_user_posts( $user_id );
512
- $user = get_user_by( 'id', $user_id );
513
  if ( $numposts > 0 ) {
514
  $value .= "<a href='edit.php?author_name=$user->user_nicename' title='" . esc_attr__( 'View posts by this author', 'co-authors-plus' ) . "' class='edit'>";
515
  $value .= $numposts;
@@ -529,7 +530,7 @@ class CoAuthors_Plus {
529
  }
530
  ?>
531
  <label class="inline-edit-group inline-edit-coauthors">
532
- <span class="title"><?php esc_html_e( 'Authors', 'co-authors-plus' ) ?></span>
533
  <div id="coauthors-edit" class="hide-if-no-js">
534
  <p><?php echo wp_kses( __( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ), array( 'strong' => array() ) ); ?></p>
535
  </div>
@@ -544,8 +545,9 @@ class CoAuthors_Plus {
544
  function _update_users_posts_count( $tt_ids, $taxonomy ) {
545
  global $wpdb;
546
 
547
- $tt_ids = implode( ', ', array_map( 'intval', $tt_ids ) );
548
- $term_ids = $wpdb->get_results( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)" );
 
549
 
550
  foreach ( (array) $term_ids as $term_id_result ) {
551
  $term = get_term_by( 'id', $term_id_result->term_id, $this->coauthor_taxonomy );
@@ -571,7 +573,7 @@ class CoAuthors_Plus {
571
 
572
  $term_id = $wpdb->get_results( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d ", $tt_id ) );
573
 
574
- $term = get_term_by( 'id', $term_id[0]->term_id, $taxonomy );
575
  $coauthor = $this->get_coauthor_by( 'user_nicename', $term->slug );
576
  if ( ! $coauthor ) {
577
  return new WP_Error( 'missing-coauthor', __( 'No co-author exists for that term', 'co-authors-plus' ) );
@@ -611,9 +613,9 @@ class CoAuthors_Plus {
611
 
612
  $query .= " WHERE ({$having_terms_and_authors}) AND {$wpdb->posts}.post_type IN ({$post_types}) AND {$wpdb->posts}.post_status = 'publish'";
613
 
614
- $query .= $wpdb->prepare( " GROUP BY {$wpdb->posts}.ID HAVING MAX( IF ( {$wpdb->term_taxonomy}.taxonomy = '%s', IF ( {$having_terms},2,1 ),0 ) ) <> 1 ", $this->coauthor_taxonomy );
615
 
616
- $count = $wpdb->query( $query );
617
  $wpdb->update( $wpdb->term_taxonomy, array( 'count' => $count ), array( 'term_taxonomy_id' => $term->term_taxonomy_id ) );
618
 
619
  wp_cache_delete( 'author-term-' . $coauthor->user_nicename, 'co-authors-plus' );
@@ -627,9 +629,9 @@ class CoAuthors_Plus {
627
 
628
  if ( $query->is_author() ) {
629
  $post_type = $query->query_vars['post_type'];
630
- if ( 'any' === $post_type ) {
631
- $post_type = get_post_types( array( 'exclude_from_search' => false ) );
632
- }
633
 
634
  if ( ! empty( $post_type ) && ! is_object_in_taxonomy( $post_type, $this->coauthor_taxonomy ) ) {
635
  return $join;
@@ -641,7 +643,7 @@ class CoAuthors_Plus {
641
 
642
  // Check to see that JOIN hasn't already been added. Props michaelingp and nbaxley
643
  $term_relationship_inner_join = " INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
644
- $term_relationship_left_join = " LEFT JOIN {$wpdb->term_relationships} AS tr1 ON ({$wpdb->posts}.ID = tr1.object_id)";
645
 
646
  $term_taxonomy_join = " INNER JOIN {$wpdb->term_taxonomy} ON ( tr1.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id )";
647
 
@@ -659,14 +661,14 @@ class CoAuthors_Plus {
659
  return $join;
660
  }
661
 
662
- /**
663
- * Modify the author query posts SQL to include posts co-authored
664
- *
665
- * @param string $where
666
- * @param WP_Query $query
667
- *
668
- * @return string
669
- */
670
  function posts_where_filter( $where, $query ) {
671
  global $wpdb;
672
 
@@ -691,7 +693,7 @@ class CoAuthors_Plus {
691
  }
692
  }
693
 
694
- $terms = array();
695
  $coauthor = $this->get_coauthor_by( 'user_nicename', $author_name );
696
  if ( $author_term = $this->get_author_term( $coauthor ) ) {
697
  $terms[] = $author_term;
@@ -715,21 +717,21 @@ class CoAuthors_Plus {
715
  $maybe_both_query = $maybe_both ? '$1 OR' : '';
716
 
717
  if ( ! empty( $terms ) ) {
718
- $terms_implode = '';
719
  $this->having_terms = '';
720
  foreach ( $terms as $term ) {
721
- $terms_implode .= '(' . $wpdb->term_taxonomy . '.taxonomy = \''. $this->coauthor_taxonomy.'\' AND '. $wpdb->term_taxonomy .'.term_id = \''. $term->term_id .'\') OR ';
722
- $this->having_terms .= ' ' . $wpdb->term_taxonomy .'.term_id = \''. $term->term_id .'\' OR ';
723
  }
724
  $terms_implode = rtrim( $terms_implode, ' OR' );
725
 
726
  // We need to check the query is the main query as a new query object would result in the wrong ID
727
  $id = is_author() && $query->is_main_query() ? get_queried_object_id() : '\d+';
728
 
729
- //If we have an ID but it's not a "real" ID that means that this isn't the first time the filter has fired and the object_id has already been replaced by a previous run of this filter. We therefore need to replace the 0
730
  // This happens when wp_query::get_posts() is run multiple times.
731
  // If previous condition resulted in this being a string there's no point wasting a db query looking for a user.
732
- if ( $id !== '\d+' && false === get_user_by( 'id', $id ) ){
733
  $id = '\d+';
734
  }
735
 
@@ -738,10 +740,10 @@ class CoAuthors_Plus {
738
 
739
  $maybe_both_query = $maybe_both ? '$0 OR' : '';
740
 
741
- $where = preg_replace( '/\s\b(?:' . $wpdb->posts . '\.)?post_author\s*IN\s*\(' . $id . '\)/', ' (' . $maybe_both_query . ' ' . $terms_implode . ')', $where, -1 ); #' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
742
 
743
  } else {
744
- $where = preg_replace( '/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(' . $id . '))/', '(' . $maybe_both_query . ' ' . $terms_implode . ')', $where, -1 ); #' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
745
  }
746
 
747
  // the block targets the private posts clause (if it exists)
@@ -754,10 +756,10 @@ class CoAuthors_Plus {
754
  $current_coauthor_term = $this->get_author_term( $current_coauthor );
755
 
756
  if ( is_a( $current_coauthor_term, 'WP_Term' ) ) {
757
- $current_user_query = $wpdb->term_taxonomy . '.taxonomy = \'' . $this->coauthor_taxonomy . '\' AND ' . $wpdb->term_taxonomy . '.term_id = \'' . $current_coauthor_term->term_id . '\'';
758
  $this->having_terms .= ' ' . $wpdb->term_taxonomy . '.term_id = \'' . $current_coauthor_term->term_id . '\' OR ';
759
 
760
- $where = preg_replace( '/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(' . get_current_user_id() . ') )/', $current_user_query . ' ', $where, -1 ); #' . $wpdb->postmeta . '.meta_id IS NOT NULL AND}
761
  }
762
  }
763
 
@@ -784,7 +786,7 @@ class CoAuthors_Plus {
784
  }
785
 
786
  if ( $this->having_terms ) {
787
- $having = 'MAX( IF ( ' . $wpdb->term_taxonomy . '.taxonomy = \''. $this->coauthor_taxonomy.'\', IF ( ' . $this->having_terms . ',2,1 ),0 ) ) <> 1 ';
788
  $groupby = $wpdb->posts . '.ID HAVING ' . $having;
789
  }
790
  }
@@ -807,10 +809,10 @@ class CoAuthors_Plus {
807
  }
808
 
809
  // This action happens when a post is saved while editing a post
810
- if ( isset( $_REQUEST['coauthors-nonce'] ) && isset( $_POST['coauthors'] ) && is_array( $_POST['coauthors'] ) ) {
811
 
812
  // rawurlencode() is for encoding coauthor name with special characters to compare names when getting coauthor.
813
- $author = rawurlencode( sanitize_text_field( $_POST['coauthors'][0] ) );
814
 
815
  if ( $author ) {
816
  $author_data = $this->get_coauthor_by( 'user_nicename', $author );
@@ -821,7 +823,7 @@ class CoAuthors_Plus {
821
  if ( is_object( $user ) ) {
822
  $data['post_author'] = $user->ID;
823
  }
824
- } else if ( 'wpuser' === $author_data->type ) {
825
  $data['post_author'] = $author_data->ID;
826
  }
827
  }
@@ -829,7 +831,7 @@ class CoAuthors_Plus {
829
 
830
  // If for some reason we don't have the co-authors fields set
831
  if ( ! isset( $data['post_author'] ) ) {
832
- $user = wp_get_current_user();
833
  $data['post_author'] = $user->ID;
834
  }
835
 
@@ -891,7 +893,7 @@ class CoAuthors_Plus {
891
  global $current_user, $wpdb;
892
 
893
  $post_id = (int) $post_id;
894
- $insert = false;
895
 
896
  // Best way to persist order
897
  if ( $append ) {
@@ -904,7 +906,7 @@ class CoAuthors_Plus {
904
  // A co-author is always required
905
  // If no coauthor is provided AND no coauthors are currently set, assign to current user - retain old ones otherwise.
906
  if ( empty( $coauthors ) ) {
907
- if( empty( $existing_coauthors ) ) {
908
  $coauthors = array( $current_user->user_login );
909
  } else {
910
  $coauthors = $existing_coauthors;
@@ -912,13 +914,13 @@ class CoAuthors_Plus {
912
  }
913
 
914
  // Set the co-authors
915
- $coauthors = array_unique( array_merge( $existing_coauthors, $coauthors ) );
916
  $coauthor_objects = array();
917
  foreach ( $coauthors as &$author_name ) {
918
- $field = apply_filters( 'coauthors_post_get_coauthor_by_field', $query_type, $author_name );
919
- $author = $this->get_coauthor_by( $field, $author_name );
920
  $coauthor_objects[] = $author;
921
- $term = $this->update_author_term( $author );
922
  if ( is_object( $term ) ) {
923
  $author_name = $term->slug;
924
  }
@@ -952,12 +954,13 @@ class CoAuthors_Plus {
952
  * Action taken when co-author is deleted.
953
  * - Co-Author term is removed from all associated posts
954
  * - Option to specify alternate co-author in place for each post
 
955
  * @param delete_id
956
  */
957
  function delete_user_action( $delete_id ) {
958
  global $wpdb;
959
 
960
- $reassign_id = isset( $_POST['reassign_user'] ) ? absint( $_POST['reassign_user'] ) : false;
961
 
962
  // If reassign posts, do that -- use coauthors_update_post
963
  if ( $reassign_id ) {
@@ -978,7 +981,8 @@ class CoAuthors_Plus {
978
  $delete_user = get_user_by( 'id', $delete_id );
979
  if ( is_object( $delete_user ) ) {
980
  // Delete term
981
- wp_delete_term( $delete_user->user_login, $this->coauthor_taxonomy );
 
982
  }
983
 
984
  if ( $this->is_guest_authors_enabled() ) {
@@ -1007,26 +1011,26 @@ class CoAuthors_Plus {
1007
  }
1008
 
1009
  global $wpdb;
1010
- $orderby = 'ORDER BY tr.term_order';
1011
- $order = 'ASC';
1012
- $object_ids = (int) $object_ids;
1013
- $query = $wpdb->prepare( "SELECT t.name, t.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN (%s) AND tr.object_id IN (%s) $orderby $order", $this->coauthor_taxonomy, $object_ids );
1014
- $raw_coauthors = $wpdb->get_results( $query );
1015
- $terms = array();
1016
  foreach ( $raw_coauthors as $author ) {
1017
  if ( true === is_array( $args ) && true === isset( $args['fields'] ) ) {
1018
  switch ( $args['fields'] ) {
1019
- case 'names' :
1020
  $terms[] = $author->name;
1021
  break;
1022
- case 'tt_ids' :
1023
  $terms[] = $author->term_taxonomy_id;
1024
  break;
1025
  case 'ids':
1026
  $terms[] = (int) $author->term_id;
1027
  break;
1028
- case 'all' :
1029
- default :
1030
  $terms[] = get_term( $author->term_id, $this->coauthor_taxonomy );
1031
  break;
1032
  }
@@ -1047,23 +1051,27 @@ class CoAuthors_Plus {
1047
  * @return int Post count
1048
  */
1049
  function filter_count_user_posts( $count, $user_id ) {
1050
- $user = get_userdata( $user_id );
 
1051
 
1052
- if ( is_object( $user ) ) {
1053
- $user = $this->get_coauthor_by( 'user_nicename', $user->user_nicename );
 
 
1054
 
1055
- $term = $this->get_author_term( $user );
1056
 
1057
- if ( $term && ! is_wp_error( $term ) ) {
1058
- if ( 'guest-author' === $user->type ) {
1059
- // If using guest author term count, add on linked user count.
1060
- $count = (int) $count + $term->count;
1061
- } else {
1062
- $count = $term->count;
1063
- }
1064
  }
 
 
 
1065
  }
1066
 
 
1067
  return $count;
1068
  }
1069
 
@@ -1079,12 +1087,10 @@ class CoAuthors_Plus {
1079
  // if user is on pages, you need to grab post type another way
1080
  $current_screen = get_current_screen();
1081
  $post_type = ( ! empty( $current_screen->post_type ) ) ? $current_screen->post_type : '';
1082
- }
1083
- else {
1084
  $post_type = $post->post_type;
1085
  }
1086
- }
1087
- else {
1088
  $post_type = $post->post_type;
1089
  }
1090
 
@@ -1094,7 +1100,7 @@ class CoAuthors_Plus {
1094
  }
1095
 
1096
  $post_type_object = get_post_type_object( $post_type );
1097
- $current_user = wp_get_current_user();
1098
  if ( ! $current_user ) {
1099
  return false;
1100
  }
@@ -1141,18 +1147,18 @@ class CoAuthors_Plus {
1141
  global $wp_query, $authordata;
1142
 
1143
  if ( is_object( $author ) ) {
1144
- $authordata = $author;
1145
- $term = $this->get_author_term( $authordata );
1146
  }
1147
 
1148
  if ( is_object( $authordata ) || ! empty( $term ) ) {
1149
- $wp_query->queried_object = $authordata;
1150
  $wp_query->queried_object_id = $authordata->ID;
1151
  add_filter( 'pre_handle_404', '__return_true' );
1152
  } else {
1153
  $wp_query->queried_object = $wp_query->queried_object_id = null;
1154
- $wp_query->is_author = $wp_query->is_archive = false;
1155
- $wp_query->is_404 = false;
1156
  }
1157
  }
1158
 
@@ -1174,7 +1180,7 @@ class CoAuthors_Plus {
1174
  $author = get_queried_object();
1175
 
1176
  if ( $author && 'guest-author' == $author->type ) {
1177
- unset( $settings['query_args'][$this->coauthor_taxonomy] );
1178
 
1179
  $settings['query_args']['author_name'] = $author->user_nicename;
1180
  }
@@ -1191,7 +1197,7 @@ class CoAuthors_Plus {
1191
  die();
1192
  }
1193
 
1194
- if ( empty( $_REQUEST['q'] ) ) {
1195
  die();
1196
  }
1197
 
@@ -1201,11 +1207,22 @@ class CoAuthors_Plus {
1201
  $authors = $this->search_authors( $search, $ignore );
1202
 
1203
  // Return message if no authors found
1204
- if( empty( $authors ) ) echo apply_filters( 'coauthors_no_matching_authors_message', 'Sorry, no matching authors found.');
 
 
1205
 
1206
  foreach ( $authors as $author ) {
1207
- $avatar_url = get_avatar_url( $author->ID );
1208
- echo esc_html( $author->ID . ' | ' . $author->user_login . ' | ' . $author->display_name . ' | ' . $author->user_email . ' | ' . rawurldecode( $author->user_nicename ) ) . ' | ' . esc_url( $avatar_url ) . "\n";
 
 
 
 
 
 
 
 
 
1209
  }
1210
 
1211
  die();
@@ -1221,17 +1238,17 @@ class CoAuthors_Plus {
1221
  // instead of the user details. If the term is missing, we probably need to
1222
  // backfill with user details. Let's do this first... easier than running
1223
  // an upgrade script that could break on a lot of users
1224
- $args = array(
1225
- 'count_total' => false,
1226
- 'search' => sprintf( '*%s*', $search ),
1227
- 'search_columns' => array(
1228
- 'ID',
1229
- 'display_name',
1230
- 'user_email',
1231
- 'user_login',
1232
- ),
1233
- 'fields' => 'all_with_meta',
1234
- );
1235
  $found_users = get_users( $args );
1236
 
1237
  foreach ( $found_users as $found_user ) {
@@ -1242,10 +1259,10 @@ class CoAuthors_Plus {
1242
  }
1243
 
1244
  $args = array(
1245
- 'search' => $search,
1246
- 'get' => 'all',
1247
- 'number' => 10,
1248
- );
1249
  $args = apply_filters( 'coauthors_search_authors_get_terms_args', $args );
1250
  add_filter( 'terms_clauses', array( $this, 'filter_terms_clauses' ) );
1251
  $found_terms = get_terms( $this->coauthor_taxonomy, $args );
@@ -1262,7 +1279,7 @@ class CoAuthors_Plus {
1262
  if ( ! $found_user && 0 === strpos( $found_term->slug, 'cap-cap-' ) ) {
1263
  // Account for guest author terms that start with 'cap-'.
1264
  // e.g. "Cap Ri" -> "cap-cap-ri".
1265
- $cap_slug = substr( $found_term->slug, 4, strlen( $found_term->slug ) );
1266
  $found_user = $this->get_coauthor_by( 'user_nicename', $cap_slug );
1267
  }
1268
  if ( ! empty( $found_user ) ) {
@@ -1276,7 +1293,7 @@ class CoAuthors_Plus {
1276
  // Make sure the user is contributor and above (or a custom cap)
1277
  if ( in_array( $found_user->user_nicename, $ignored_authors, true ) ) { // AJAX sends a list of already present *users_nicenames*
1278
  unset( $found_users[ $key ] );
1279
- } else if ( 'wpuser' === $found_user->type && false === $found_user->has_cap( apply_filters( 'coauthors_edit_author_cap', 'edit_posts' ) ) ) {
1280
  unset( $found_users[ $key ] );
1281
  }
1282
  }
@@ -1310,13 +1327,13 @@ class CoAuthors_Plus {
1310
  wp_enqueue_script( 'co-authors-plus-js', plugins_url( 'js/co-authors-plus.js', __FILE__ ), array( 'jquery', 'suggest' ), COAUTHORS_PLUS_VERSION, true );
1311
 
1312
  $js_strings = array(
1313
- 'edit_label' => __( 'Edit', 'co-authors-plus' ),
1314
- 'delete_label' => __( 'Remove', 'co-authors-plus' ),
1315
- 'confirm_delete' => __( 'Are you sure you want to remove this author?', 'co-authors-plus' ),
1316
  'input_box_title' => __( 'Click to change this author, or drag to change their position', 'co-authors-plus' ),
1317
  'search_box_text' => __( 'Search for an author', 'co-authors-plus' ),
1318
- 'help_text' => __( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ),
1319
- );
1320
  wp_localize_script( 'co-authors-plus-js', 'coAuthorsPlusStrings', $js_strings );
1321
 
1322
  }
@@ -1343,11 +1360,11 @@ class CoAuthors_Plus {
1343
  return $views;
1344
  }
1345
 
1346
- $views = array_reverse( $views );
1347
- $all_view = array_pop( $views );
1348
  $mine_args = array(
1349
- 'author_name' => wp_get_current_user()->user_nicename,
1350
- );
1351
  if ( 'post' != get_post_type() ) {
1352
  $mine_args['post_type'] = get_current_screen()->post_type;
1353
  }
@@ -1359,7 +1376,7 @@ class CoAuthors_Plus {
1359
  $views['mine'] = $view_mine = '<a' . $class . ' href="' . esc_url( add_query_arg( array_map( 'rawurlencode', $mine_args ), admin_url( 'edit.php' ) ) ) . '">' . __( 'Mine', 'co-authors-plus' ) . '</a>';
1360
 
1361
  $views['all'] = str_replace( $class, '', $all_view );
1362
- $views = array_reverse( $views );
1363
 
1364
  return $views;
1365
  }
@@ -1369,22 +1386,25 @@ class CoAuthors_Plus {
1369
  */
1370
  public function js_vars() {
1371
 
1372
- if ( ! $this->is_valid_page() || ! $this->is_post_type_enabled() || ! $this-> current_user_can_set_authors() ) {
1373
  return;
1374
  }
1375
  ?>
1376
  <script type="text/javascript">
1377
  // AJAX link used for the autosuggest
1378
- var coAuthorsPlus_ajax_suggest_link = <?php
 
1379
  echo wp_json_encode(
1380
  add_query_arg(
1381
  array(
1382
- 'action' => 'coauthors_ajax_suggest',
1383
  'post_type' => rawurlencode( get_post_type() ),
1384
  ),
1385
  wp_nonce_url( 'admin-ajax.php', 'coauthors-search' )
1386
  )
1387
- ); ?>;
 
 
1388
  </script>
1389
  <?php
1390
  }
@@ -1410,11 +1430,11 @@ class CoAuthors_Plus {
1410
  * @return array caps that CAP should filter
1411
  */
1412
  public function get_to_be_filtered_caps() {
1413
- if( ! empty( $this->supported_post_types ) && empty( $this->to_be_filtered_caps ) ) {
1414
  $this->to_be_filtered_caps[] = 'edit_post'; // Need to filter this too, unfortunately: http://core.trac.wordpress.org/ticket/22415
1415
  $this->to_be_filtered_caps[] = 'read_post';
1416
 
1417
- foreach( $this->supported_post_types as $single ) {
1418
  $obj = get_post_type_object( $single );
1419
 
1420
  $this->to_be_filtered_caps[] = $obj->cap->edit_post;
@@ -1433,11 +1453,11 @@ class CoAuthors_Plus {
1433
  */
1434
  function filter_user_has_cap( $allcaps, $caps, $args ) {
1435
 
1436
- $cap = $args[0];
1437
  $user_id = isset( $args[1] ) ? $args[1] : 0;
1438
  $post_id = isset( $args[2] ) ? $args[2] : 0;
1439
 
1440
- if( ! in_array( $cap, $this->get_to_be_filtered_caps(), true ) ) {
1441
  return $allcaps;
1442
  }
1443
 
@@ -1446,14 +1466,14 @@ class CoAuthors_Plus {
1446
  return $allcaps;
1447
  }
1448
 
1449
- //Even though we bail if cap is not among the to_be_filtered ones, there is a time in early request processing in which that list is not yet available, so the following block is needed
1450
  $caps_to_modify = array(
1451
- $obj->cap->edit_post,
1452
- 'edit_post', // Need to filter this too, unfortunately: http://core.trac.wordpress.org/ticket/22415
1453
- $obj->cap->edit_others_posts, // This as well: http://core.trac.wordpress.org/ticket/22417
1454
- 'read_post',
1455
- $obj->cap->read_post,
1456
- );
1457
  if ( ! in_array( $cap, $caps_to_modify ) ) {
1458
  return $allcaps;
1459
  }
@@ -1532,9 +1552,9 @@ class CoAuthors_Plus {
1532
  }
1533
  } else {
1534
  $coauthor_slug = 'cap-' . $coauthor->user_nicename;
1535
- $args = array(
1536
- 'slug' => $coauthor_slug,
1537
- 'description' => $term_description,
1538
  );
1539
 
1540
  $new_term = wp_insert_term( $coauthor->user_login, $this->coauthor_taxonomy, $args );
@@ -1549,7 +1569,7 @@ class CoAuthors_Plus {
1549
  * @see https://github.com/Automattic/Co-Authors-Plus/issues/2
1550
  *
1551
  * @param array $information_fields
1552
- * @param int $post_id
1553
  * @return array
1554
  */
1555
  function filter_ef_calendar_item_information_fields( $information_fields, $post_id ) {
@@ -1561,13 +1581,13 @@ class CoAuthors_Plus {
1561
 
1562
  $co_authors = get_coauthors( $post_id );
1563
  if ( count( $co_authors ) > 1 ) {
1564
- $information_fields[$this->coauthor_taxonomy]['label'] = __( 'Authors', 'co-authors-plus' );
1565
  }
1566
  $co_authors_names = '';
1567
  foreach ( $co_authors as $co_author ) {
1568
  $co_authors_names .= $co_author->display_name . ', ';
1569
  }
1570
- $information_fields[$this->coauthor_taxonomy]['value'] = rtrim( $co_authors_names, ', ' );
1571
  return $information_fields;
1572
  }
1573
 
@@ -1588,7 +1608,7 @@ class CoAuthors_Plus {
1588
  return $column_name;
1589
  }
1590
 
1591
- $co_authors = get_coauthors( $post->ID );
1592
  $co_authors_names = '';
1593
  foreach ( $co_authors as $co_author ) {
1594
  $co_authors_names .= $co_author->display_name . ', ';
@@ -1608,7 +1628,7 @@ class CoAuthors_Plus {
1608
  public function filter_jetpack_open_graph_tags( $og_tags, $image_dimensions ) {
1609
 
1610
  if ( is_author() ) {
1611
- $author = get_queried_object();
1612
  $og_tags['og:title'] = $author->display_name;
1613
  $og_tags['og:url'] = get_author_posts_url( $author->ID, $author->user_nicename );
1614
  $og_tags['og:description'] = $author->description;
@@ -1617,7 +1637,7 @@ class CoAuthors_Plus {
1617
  if ( isset( $og_tags['article:author'] ) ) {
1618
  $og_tags['article:author'] = get_author_posts_url( $author->ID, $author->user_nicename );
1619
  }
1620
- } else if ( is_singular() && $this->is_post_type_enabled() ) {
1621
  $authors = get_coauthors();
1622
  if ( ! empty( $authors ) ) {
1623
  $author = array_shift( $authors );
@@ -1646,14 +1666,18 @@ class CoAuthors_Plus {
1646
  return array();
1647
  }
1648
 
1649
- $cache_key = 'coauthors_post_' . $post_id;
1650
  $coauthor_terms = wp_cache_get( $cache_key, 'co-authors-plus' );
1651
 
1652
  if ( false === $coauthor_terms ) {
1653
- $coauthor_terms = wp_get_object_terms( $post_id, $this->coauthor_taxonomy, array(
1654
- 'orderby' => 'term_order',
1655
- 'order' => 'ASC',
1656
- ) );
 
 
 
 
1657
 
1658
  // This usually happens if the taxonomy doesn't exist, which should never happen, but you never know.
1659
  if ( is_wp_error( $coauthor_terms ) ) {
@@ -1707,7 +1731,7 @@ class CoAuthors_Plus {
1707
  }
1708
 
1709
  $author_slug = sanitize_user( get_query_var( 'author_name' ) );
1710
- $author = $this->get_coauthor_by( 'user_nicename', $author_slug );
1711
 
1712
  return sprintf( __( 'Author: %s' ), $author->display_name );
1713
  }
@@ -1731,7 +1755,7 @@ class CoAuthors_Plus {
1731
  && $guest_term->count ) {
1732
  $user = get_user_by( 'login', $guest_author->linked_account );
1733
  if ( is_object( $user ) ) {
1734
- return count_user_posts( $user->ID );
1735
  }
1736
  } elseif ( $term ) {
1737
  return $term->count;
@@ -1753,9 +1777,11 @@ class CoAuthors_Plus {
1753
  return $args;
1754
  }
1755
  $coauthor = $this->get_coauthor_by( 'id', $id );
1756
- if ( false !== $coauthor && isset( $coauthor->type ) && 'guest-author' === $coauthor->type ) {
1757
  if ( has_post_thumbnail( $id ) ) {
1758
  $args['url'] = get_the_post_thumbnail_url( $id, $this->gravatar_size );
 
 
1759
  } else {
1760
  $args['url'] = get_avatar_url( '' ); // Fallback to default.
1761
  }
@@ -1775,13 +1801,13 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1775
  *
1776
  * @since 2.6.2
1777
  *
1778
- * @param int $comment_id Comment ID
1779
  * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback'
1780
  * @return bool False if user email does not exist. True on completion.
1781
  */
1782
  function wp_notify_postauthor( $comment_id, $comment_type = '' ) {
1783
- $comment = get_comment( $comment_id );
1784
- $post = get_post( $comment->comment_post_ID );
1785
  $coauthors = get_coauthors( $post->ID );
1786
  foreach ( $coauthors as $author ) {
1787
 
@@ -1811,7 +1837,7 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1811
  }
1812
 
1813
  if ( 'comment' == $comment_type ) {
1814
- $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n";
1815
  /* translators: 1: comment author, 2: author IP, 3: author domain */
1816
  $notify_message .= sprintf( __( 'Author : %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1817
  $notify_message .= sprintf( __( 'E-mail : %s' ), $comment->comment_author_email ) . "\r\n";
@@ -1822,7 +1848,7 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1822
  /* translators: 1: blog name, 2: post title */
1823
  $subject = sprintf( __( '[%1$s] Comment: "%2$s"' ), $blogname, $post->post_title );
1824
  } elseif ( 'trackback' == $comment_type ) {
1825
- $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n";
1826
  /* translators: 1: website name, 2: author IP, 3: author domain */
1827
  $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1828
  $notify_message .= sprintf( __( 'URL : %s' ), $comment->comment_author_url ) . "\r\n";
@@ -1831,7 +1857,7 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1831
  /* translators: 1: blog name, 2: post title */
1832
  $subject = sprintf( __( '[%1$s] Trackback: "%2$s"' ), $blogname, $post->post_title );
1833
  } elseif ( 'pingback' == $comment_type ) {
1834
- $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n";
1835
  /* translators: 1: comment author, 2: author IP, 3: author domain */
1836
  $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1837
  $notify_message .= sprintf( __( 'URL : %s' ), $comment->comment_author_url ) . "\r\n";
@@ -1849,7 +1875,7 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1849
  }
1850
  $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c=$comment_id" ) ) . "\r\n";
1851
 
1852
- $wp_email = 'wordpress@' . preg_replace( '#^www\.#', '', strtolower( $_SERVER['SERVER_NAME'] ) );
1853
 
1854
  if ( '' == $comment->comment_author ) {
1855
  $from = "From: \"$blogname\" <$wp_email>";
@@ -1870,8 +1896,8 @@ if ( ! function_exists( 'wp_notify_postauthor' ) ) :
1870
  $message_headers .= $reply_to . "\n";
1871
  }
1872
 
1873
- $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment_id );
1874
- $subject = apply_filters( 'comment_notification_subject', $subject, $comment_id );
1875
  $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment_id );
1876
 
1877
  @wp_mail( $author->user_email, $subject, $notify_message, $message_headers );
@@ -1885,7 +1911,7 @@ endif;
1885
  * Filter array of moderation notification email addresses
1886
  *
1887
  * @param array $recipients
1888
- * @param int $comment_id
1889
  * @return array
1890
  */
1891
  function cap_filter_comment_moderation_email_recipients( $recipients, $comment_id ) {
@@ -1893,7 +1919,7 @@ function cap_filter_comment_moderation_email_recipients( $recipients, $comment_i
1893
  $post_id = $comment->comment_post_ID;
1894
 
1895
  if ( isset( $post_id ) ) {
1896
- $coauthors = get_coauthors( $post_id );
1897
  $extra_recipients = array();
1898
  foreach ( $coauthors as $user ) {
1899
  if ( ! empty( $user->user_email ) ) {
@@ -1918,4 +1944,4 @@ function cap_filter_comment_moderation_email_recipients( $recipients, $comment_i
1918
  function cap_get_coauthor_terms_for_post( $post_id ) {
1919
  global $coauthors_plus;
1920
  return $coauthors_plus->get_coauthor_terms_for_post( $post_id );
1921
- }
3
  Plugin Name: Co-Authors Plus
4
  Plugin URI: http://wordpress.org/extend/plugins/co-authors-plus/
5
  Description: Allows multiple authors to be assigned to a post. This plugin is an extended version of the Co-Authors plugin developed by Weston Ruter.
6
+ Version: 3.4.6
7
  Author: Mohammad Jangda, Daniel Bachhuber, Automattic
8
  Copyright: 2008-2015 Shared and distributed between Mohammad Jangda, Daniel Bachhuber, Weston Ruter
9
 
32
  Author - user with the role of author
33
  */
34
 
35
+ define( 'COAUTHORS_PLUS_VERSION', '3.4.6' );
36
 
37
+ require_once dirname( __FILE__ ) . '/template-tags.php';
38
+ require_once dirname( __FILE__ ) . '/deprecated.php';
39
 
40
+ require_once dirname( __FILE__ ) . '/php/class-coauthors-template-filters.php';
41
+ require_once dirname( __FILE__ ) . '/php/integrations/amp.php';
42
 
43
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
44
+ require_once dirname( __FILE__ ) . '/php/class-wp-cli.php';
45
  }
46
 
47
  class CoAuthors_Plus {
51
  var $coauthor_taxonomy = 'author';
52
 
53
  var $coreauthors_meta_box_name = 'authordiv';
54
+ var $coauthors_meta_box_name = 'coauthorsdiv';
55
+ var $force_guest_authors = false;
56
 
57
  var $gravatar_size = 25;
58
 
89
  add_filter( 'wp_insert_post_data', array( $this, 'coauthors_set_post_author_field' ), 10, 2 );
90
 
91
  // Action to reassign posts when a guest author is deleted
92
+ add_action( 'delete_user', array( $this, 'delete_user_action' ) );
93
 
94
  add_filter( 'get_usernumposts', array( $this, 'filter_count_user_posts' ), 10, 2 );
95
 
127
  add_filter( 'infinite_scroll_js_settings', array( $this, 'filter_infinite_scroll_js_settings' ), 10, 2 );
128
 
129
  // Delete Co-Author Cache on Post Save & Post Delete
130
+ add_action( 'save_post', array( $this, 'clear_cache' ) );
131
+ add_action( 'delete_post', array( $this, 'clear_cache' ) );
132
  add_action( 'set_object_terms', array( $this, 'clear_cache_on_terms_set' ), 10, 6 );
133
 
134
  // Filter to correct author on author archive page
135
+ add_filter( 'get_the_archive_title', array( $this, 'filter_author_archive_title' ), 10, 1 );
136
 
137
  // Filter to display author image if exists instead of avatar
138
  add_filter( 'pre_get_avatar_data', array( $this, 'filter_pre_get_avatar_data_url' ), 10, 2 );
149
 
150
  // Load the Guest Authors functionality if needed
151
  if ( $this->is_guest_authors_enabled() ) {
152
+ require_once dirname( __FILE__ ) . '/php/class-coauthors-guest-authors.php';
153
+ $this->guest_authors = new CoAuthors_Guest_Authors();
154
  if ( apply_filters( 'coauthors_guest_authors_force', false ) ) {
155
  $this->force_guest_authors = true;
156
  }
159
  // Maybe automatically apply our template tags
160
  if ( apply_filters( 'coauthors_auto_apply_template_tags', false ) ) {
161
  global $coauthors_plus_template_filters;
162
+ $coauthors_plus_template_filters = new CoAuthors_Template_Filters();
163
  }
164
 
165
  }
172
  // Register new taxonomy so that we can store all of the relationships
173
  $args = array(
174
  'hierarchical' => false,
175
+ 'label' => false,
176
+ 'query_var' => false,
177
+ 'rewrite' => false,
178
+ 'public' => false,
179
+ 'sort' => true,
180
+ 'args' => array( 'orderby' => 'term_order' ),
181
+ 'show_ui' => false,
182
  );
183
 
184
  // If we use the nasty SQL query, we need our custom callback. Otherwise, we still need to flush cache.
272
  if ( 'user_nicename' == $key ) {
273
  $key = 'slug';
274
  }
275
+ $user = get_user_by( $key, $value );
276
+ if ( ! $user && ( 'login' == $key || 'slug' == $key ) ) {
277
+ // Re-try lookup without prefixed value if no results found.
278
  $value = preg_replace( '#^cap\-#', '', $value );
279
+ $user = get_user_by( $key, $value );
280
  }
 
281
  if ( ! $user ) {
282
  return false;
283
  }
310
 
311
  if ( ! $post_type ) {
312
  $post_type = get_post_type();
313
+ if ( is_admin() && ! $post_type ) {
314
  $post_type = get_current_screen()->post_type;
315
  }
316
  }
464
  $count = 1;
465
  foreach ( $authors as $author ) :
466
  $args = array(
467
+ 'author_name' => $author->user_nicename,
468
+ );
469
  if ( 'post' != $post->post_type ) {
470
  $args['post_type'] = $post->post_type;
471
  }
472
  $author_filter_url = add_query_arg( array_map( 'rawurlencode', $args ), admin_url( 'edit.php' ) );
473
  ?>
474
  <a href="<?php echo esc_url( $author_filter_url ); ?>"
475
+ data-user_nicename="<?php echo esc_attr( $author->user_nicename ); ?>"
476
+ data-user_email="<?php echo esc_attr( $author->user_email ); ?>"
477
+ data-display_name="<?php echo esc_attr( $author->display_name ); ?>"
478
+ data-user_login="<?php echo esc_attr( $author->user_login ); ?>"
479
+ data-avatar="<?php echo esc_attr( get_avatar_url( $author->ID ) ); ?>"
480
  ><?php echo esc_html( $author->display_name ); ?></a><?php echo ( $count < count( $authors ) ) ? ',' : ''; ?>
481
  <?php
482
  $count++;
509
  return $value;
510
  }
511
  // We filter count_user_posts() so it provides an accurate number
512
+ $numposts = count_user_posts( $user_id ); // phpcs:ignore
513
+ $user = get_user_by( 'id', $user_id );
514
  if ( $numposts > 0 ) {
515
  $value .= "<a href='edit.php?author_name=$user->user_nicename' title='" . esc_attr__( 'View posts by this author', 'co-authors-plus' ) . "' class='edit'>";
516
  $value .= $numposts;
530
  }
531
  ?>
532
  <label class="inline-edit-group inline-edit-coauthors">
533
+ <span class="title"><?php esc_html_e( 'Authors', 'co-authors-plus' ); ?></span>
534
  <div id="coauthors-edit" class="hide-if-no-js">
535
  <p><?php echo wp_kses( __( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ), array( 'strong' => array() ) ); ?></p>
536
  </div>
545
  function _update_users_posts_count( $tt_ids, $taxonomy ) {
546
  global $wpdb;
547
 
548
+ $tt_ids = implode( ', ', array_map( 'intval', $tt_ids ) );
549
+ $term_ids = $wpdb->get_results( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN (%s)", $tt_ids ) );
550
+
551
 
552
  foreach ( (array) $term_ids as $term_id_result ) {
553
  $term = get_term_by( 'id', $term_id_result->term_id, $this->coauthor_taxonomy );
573
 
574
  $term_id = $wpdb->get_results( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d ", $tt_id ) );
575
 
576
+ $term = get_term_by( 'id', $term_id[0]->term_id, $taxonomy );
577
  $coauthor = $this->get_coauthor_by( 'user_nicename', $term->slug );
578
  if ( ! $coauthor ) {
579
  return new WP_Error( 'missing-coauthor', __( 'No co-author exists for that term', 'co-authors-plus' ) );
613
 
614
  $query .= " WHERE ({$having_terms_and_authors}) AND {$wpdb->posts}.post_type IN ({$post_types}) AND {$wpdb->posts}.post_status = 'publish'";
615
 
616
+ $query .= $wpdb->prepare( " GROUP BY {$wpdb->posts}.ID HAVING MAX( IF ( {$wpdb->term_taxonomy}.taxonomy = '%s', IF ( {$having_terms},2,1 ),0 ) ) <> 1 ", $this->coauthor_taxonomy ); //phpcs:ignore
617
 
618
+ $count = $wpdb->query( $query ); // phpcs:ignore
619
  $wpdb->update( $wpdb->term_taxonomy, array( 'count' => $count ), array( 'term_taxonomy_id' => $term->term_taxonomy_id ) );
620
 
621
  wp_cache_delete( 'author-term-' . $coauthor->user_nicename, 'co-authors-plus' );
629
 
630
  if ( $query->is_author() ) {
631
  $post_type = $query->query_vars['post_type'];
632
+ if ( 'any' === $post_type ) {
633
+ $post_type = get_post_types( array( 'exclude_from_search' => false ) );
634
+ }
635
 
636
  if ( ! empty( $post_type ) && ! is_object_in_taxonomy( $post_type, $this->coauthor_taxonomy ) ) {
637
  return $join;
643
 
644
  // Check to see that JOIN hasn't already been added. Props michaelingp and nbaxley
645
  $term_relationship_inner_join = " INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
646
+ $term_relationship_left_join = " LEFT JOIN {$wpdb->term_relationships} AS tr1 ON ({$wpdb->posts}.ID = tr1.object_id)";
647
 
648
  $term_taxonomy_join = " INNER JOIN {$wpdb->term_taxonomy} ON ( tr1.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id )";
649
 
661
  return $join;
662
  }
663
 
664
+ /**
665
+ * Modify the author query posts SQL to include posts co-authored
666
+ *
667
+ * @param string $where
668
+ * @param WP_Query $query
669
+ *
670
+ * @return string
671
+ */
672
  function posts_where_filter( $where, $query ) {
673
  global $wpdb;
674
 
693
  }
694
  }
695
 
696
+ $terms = array();
697
  $coauthor = $this->get_coauthor_by( 'user_nicename', $author_name );
698
  if ( $author_term = $this->get_author_term( $coauthor ) ) {
699
  $terms[] = $author_term;
717
  $maybe_both_query = $maybe_both ? '$1 OR' : '';
718
 
719
  if ( ! empty( $terms ) ) {
720
+ $terms_implode = '';
721
  $this->having_terms = '';
722
  foreach ( $terms as $term ) {
723
+ $terms_implode .= '(' . $wpdb->term_taxonomy . '.taxonomy = \'' . $this->coauthor_taxonomy . '\' AND ' . $wpdb->term_taxonomy . '.term_id = \'' . $term->term_id . '\') OR ';
724
+ $this->having_terms .= ' ' . $wpdb->term_taxonomy . '.term_id = \'' . $term->term_id . '\' OR ';
725
  }
726
  $terms_implode = rtrim( $terms_implode, ' OR' );
727
 
728
  // We need to check the query is the main query as a new query object would result in the wrong ID
729
  $id = is_author() && $query->is_main_query() ? get_queried_object_id() : '\d+';
730
 
731
+ // If we have an ID but it's not a "real" ID that means that this isn't the first time the filter has fired and the object_id has already been replaced by a previous run of this filter. We therefore need to replace the 0
732
  // This happens when wp_query::get_posts() is run multiple times.
733
  // If previous condition resulted in this being a string there's no point wasting a db query looking for a user.
734
+ if ( $id !== '\d+' && false === get_user_by( 'id', $id ) ) {
735
  $id = '\d+';
736
  }
737
 
740
 
741
  $maybe_both_query = $maybe_both ? '$0 OR' : '';
742
 
743
+ $where = preg_replace( '/\s\b(?:' . $wpdb->posts . '\.)?post_author\s*IN\s*\(' . $id . '\)/', ' (' . $maybe_both_query . ' ' . $terms_implode . ')', $where, -1 ); // ' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
744
 
745
  } else {
746
+ $where = preg_replace( '/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(' . $id . '))/', '(' . $maybe_both_query . ' ' . $terms_implode . ')', $where, -1 ); // ' . $wpdb->postmeta . '.meta_id IS NOT NULL AND
747
  }
748
 
749
  // the block targets the private posts clause (if it exists)
756
  $current_coauthor_term = $this->get_author_term( $current_coauthor );
757
 
758
  if ( is_a( $current_coauthor_term, 'WP_Term' ) ) {
759
+ $current_user_query = $wpdb->term_taxonomy . '.taxonomy = \'' . $this->coauthor_taxonomy . '\' AND ' . $wpdb->term_taxonomy . '.term_id = \'' . $current_coauthor_term->term_id . '\'';
760
  $this->having_terms .= ' ' . $wpdb->term_taxonomy . '.term_id = \'' . $current_coauthor_term->term_id . '\' OR ';
761
 
762
+ $where = preg_replace( '/(\b(?:' . $wpdb->posts . '\.)?post_author\s*=\s*(' . get_current_user_id() . ') )/', $current_user_query . ' ', $where, -1 ); // ' . $wpdb->postmeta . '.meta_id IS NOT NULL AND}
763
  }
764
  }
765
 
786
  }
787
 
788
  if ( $this->having_terms ) {
789
+ $having = 'MAX( IF ( ' . $wpdb->term_taxonomy . '.taxonomy = \'' . $this->coauthor_taxonomy . '\', IF ( ' . $this->having_terms . ',2,1 ),0 ) ) <> 1 ';
790
  $groupby = $wpdb->posts . '.ID HAVING ' . $having;
791
  }
792
  }
809
  }
810
 
811
  // This action happens when a post is saved while editing a post
812
+ if ( isset( $_REQUEST['coauthors-nonce'] ) && isset( $_POST['coauthors'] ) && is_array( $_POST['coauthors'] ) ) { // phpcs:ignore
813
 
814
  // rawurlencode() is for encoding coauthor name with special characters to compare names when getting coauthor.
815
+ $author = rawurlencode( sanitize_text_field( $_POST['coauthors'][0] ) ); // phpcs:ignore
816
 
817
  if ( $author ) {
818
  $author_data = $this->get_coauthor_by( 'user_nicename', $author );
823
  if ( is_object( $user ) ) {
824
  $data['post_author'] = $user->ID;
825
  }
826
+ } elseif ( 'wpuser' === $author_data->type ) {
827
  $data['post_author'] = $author_data->ID;
828
  }
829
  }
831
 
832
  // If for some reason we don't have the co-authors fields set
833
  if ( ! isset( $data['post_author'] ) ) {
834
+ $user = wp_get_current_user();
835
  $data['post_author'] = $user->ID;
836
  }
837
 
893
  global $current_user, $wpdb;
894
 
895
  $post_id = (int) $post_id;
896
+ $insert = false;
897
 
898
  // Best way to persist order
899
  if ( $append ) {
906
  // A co-author is always required
907
  // If no coauthor is provided AND no coauthors are currently set, assign to current user - retain old ones otherwise.
908
  if ( empty( $coauthors ) ) {
909
+ if ( empty( $existing_coauthors ) ) {
910
  $coauthors = array( $current_user->user_login );
911
  } else {
912
  $coauthors = $existing_coauthors;
914
  }
915
 
916
  // Set the co-authors
917
+ $coauthors = array_unique( array_merge( $existing_coauthors, $coauthors ) );
918
  $coauthor_objects = array();
919
  foreach ( $coauthors as &$author_name ) {
920
+ $field = apply_filters( 'coauthors_post_get_coauthor_by_field', $query_type, $author_name );
921
+ $author = $this->get_coauthor_by( $field, $author_name );
922
  $coauthor_objects[] = $author;
923
+ $term = $this->update_author_term( $author );
924
  if ( is_object( $term ) ) {
925
  $author_name = $term->slug;
926
  }
954
  * Action taken when co-author is deleted.
955
  * - Co-Author term is removed from all associated posts
956
  * - Option to specify alternate co-author in place for each post
957
+ *
958
  * @param delete_id
959
  */
960
  function delete_user_action( $delete_id ) {
961
  global $wpdb;
962
 
963
+ $reassign_id = isset( $_POST['reassign_user'] ) ? absint( $_POST['reassign_user'] ) : false; // phpcs:ignore
964
 
965
  // If reassign posts, do that -- use coauthors_update_post
966
  if ( $reassign_id ) {
981
  $delete_user = get_user_by( 'id', $delete_id );
982
  if ( is_object( $delete_user ) ) {
983
  // Delete term
984
+ $term = $this->get_author_term( $delete_user );
985
+ wp_delete_term( $term->term_id, $this->coauthor_taxonomy );
986
  }
987
 
988
  if ( $this->is_guest_authors_enabled() ) {
1011
  }
1012
 
1013
  global $wpdb;
1014
+ $orderby = 'ORDER BY tr.term_order';
1015
+ $order = 'ASC';
1016
+ $object_ids = (int) $object_ids;
1017
+ $query = $wpdb->prepare( "SELECT t.name, t.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN (%s) AND tr.object_id IN (%s) $orderby $order", $this->coauthor_taxonomy, $object_ids ); //phpcs:ignore
1018
+ $raw_coauthors = $wpdb->get_results( $query ); //phpcs:ignore
1019
+ $terms = array();
1020
  foreach ( $raw_coauthors as $author ) {
1021
  if ( true === is_array( $args ) && true === isset( $args['fields'] ) ) {
1022
  switch ( $args['fields'] ) {
1023
+ case 'names':
1024
  $terms[] = $author->name;
1025
  break;
1026
+ case 'tt_ids':
1027
  $terms[] = $author->term_taxonomy_id;
1028
  break;
1029
  case 'ids':
1030
  $terms[] = (int) $author->term_id;
1031
  break;
1032
+ case 'all':
1033
+ default:
1034
  $terms[] = get_term( $author->term_id, $this->coauthor_taxonomy );
1035
  break;
1036
  }
1051
  * @return int Post count
1052
  */
1053
  function filter_count_user_posts( $count, $user_id ) {
1054
+ $user = get_userdata( $user_id );
1055
+ $coauthor = $this->get_coauthor_by( 'user_nicename', $user->user_nicename );
1056
 
1057
+ // Return $count, if no coauthor exists.
1058
+ if ( ! is_object( $coauthor ) ) {
1059
+ return $count;
1060
+ }
1061
 
1062
+ $term = $this->get_author_term( $coauthor );
1063
 
1064
+ if ( is_object( $term ) ) {
1065
+ // Return combined post count, if account is linked.
1066
+ if ( strlen( $coauthor->linked_account ) > 2 ) {
1067
+ return $count + $term->count;
 
 
 
1068
  }
1069
+
1070
+ // Otherwise, return the term count.
1071
+ return $term->count;
1072
  }
1073
 
1074
+ // Return $count as fallback.
1075
  return $count;
1076
  }
1077
 
1087
  // if user is on pages, you need to grab post type another way
1088
  $current_screen = get_current_screen();
1089
  $post_type = ( ! empty( $current_screen->post_type ) ) ? $current_screen->post_type : '';
1090
+ } else {
 
1091
  $post_type = $post->post_type;
1092
  }
1093
+ } else {
 
1094
  $post_type = $post->post_type;
1095
  }
1096
 
1100
  }
1101
 
1102
  $post_type_object = get_post_type_object( $post_type );
1103
+ $current_user = wp_get_current_user();
1104
  if ( ! $current_user ) {
1105
  return false;
1106
  }
1147
  global $wp_query, $authordata;
1148
 
1149
  if ( is_object( $author ) ) {
1150
+ $authordata = $author; //phpcs:ignore
1151
+ $term = $this->get_author_term( $authordata );
1152
  }
1153
 
1154
  if ( is_object( $authordata ) || ! empty( $term ) ) {
1155
+ $wp_query->queried_object = $authordata;
1156
  $wp_query->queried_object_id = $authordata->ID;
1157
  add_filter( 'pre_handle_404', '__return_true' );
1158
  } else {
1159
  $wp_query->queried_object = $wp_query->queried_object_id = null;
1160
+ $wp_query->is_author = $wp_query->is_archive = false;
1161
+ $wp_query->is_404 = false;
1162
  }
1163
  }
1164
 
1180
  $author = get_queried_object();
1181
 
1182
  if ( $author && 'guest-author' == $author->type ) {
1183
+ unset( $settings['query_args'][ $this->coauthor_taxonomy ] );
1184
 
1185
  $settings['query_args']['author_name'] = $author->user_nicename;
1186
  }
1197
  die();
1198
  }
1199
 
1200
+ if ( empty( $_REQUEST['q'] ) || empty( $_REQUEST['existing_authors'] ) ) {
1201
  die();
1202
  }
1203
 
1207
  $authors = $this->search_authors( $search, $ignore );
1208
 
1209
  // Return message if no authors found
1210
+ if ( empty( $authors ) ) {
1211
+ echo esc_html( apply_filters( 'coauthors_no_matching_authors_message', 'Sorry, no matching authors found.' ) );
1212
+ }
1213
 
1214
  foreach ( $authors as $author ) {
1215
+ printf(
1216
+ "%s %s %s %s %s %s \n",
1217
+ esc_html( $author->ID ),
1218
+ esc_html( $author->user_login ),
1219
+ // Ensure that author names can contain a pipe character by replacing the pipe character with the
1220
+ // divides character, which will now serve as a delimiter of the author parameters. (#370)
1221
+ esc_html( str_replace( '∣', '|', $author->display_name ) ),
1222
+ esc_html( $author->user_email ),
1223
+ esc_html( rawurldecode( $author->user_nicename ) ),
1224
+ esc_url( get_avatar_url( $author->ID ) )
1225
+ );
1226
  }
1227
 
1228
  die();
1238
  // instead of the user details. If the term is missing, we probably need to
1239
  // backfill with user details. Let's do this first... easier than running
1240
  // an upgrade script that could break on a lot of users
1241
+ $args = array(
1242
+ 'count_total' => false,
1243
+ 'search' => sprintf( '*%s*', $search ),
1244
+ 'search_columns' => array(
1245
+ 'ID',
1246
+ 'display_name',
1247
+ 'user_email',
1248
+ 'user_login',
1249
+ ),
1250
+ 'fields' => 'all_with_meta',
1251
+ );
1252
  $found_users = get_users( $args );
1253
 
1254
  foreach ( $found_users as $found_user ) {
1259
  }
1260
 
1261
  $args = array(
1262
+ 'search' => $search,
1263
+ 'get' => 'all',
1264
+ 'number' => 10,
1265
+ );
1266
  $args = apply_filters( 'coauthors_search_authors_get_terms_args', $args );
1267
  add_filter( 'terms_clauses', array( $this, 'filter_terms_clauses' ) );
1268
  $found_terms = get_terms( $this->coauthor_taxonomy, $args );
1279
  if ( ! $found_user && 0 === strpos( $found_term->slug, 'cap-cap-' ) ) {
1280
  // Account for guest author terms that start with 'cap-'.
1281
  // e.g. "Cap Ri" -> "cap-cap-ri".
1282
+ $cap_slug = substr( $found_term->slug, 4, strlen( $found_term->slug ) );
1283
  $found_user = $this->get_coauthor_by( 'user_nicename', $cap_slug );
1284
  }
1285
  if ( ! empty( $found_user ) ) {
1293
  // Make sure the user is contributor and above (or a custom cap)
1294
  if ( in_array( $found_user->user_nicename, $ignored_authors, true ) ) { // AJAX sends a list of already present *users_nicenames*
1295
  unset( $found_users[ $key ] );
1296
+ } elseif ( 'wpuser' === $found_user->type && false === $found_user->has_cap( apply_filters( 'coauthors_edit_author_cap', 'edit_posts' ) ) ) {
1297
  unset( $found_users[ $key ] );
1298
  }
1299
  }
1327
  wp_enqueue_script( 'co-authors-plus-js', plugins_url( 'js/co-authors-plus.js', __FILE__ ), array( 'jquery', 'suggest' ), COAUTHORS_PLUS_VERSION, true );
1328
 
1329
  $js_strings = array(
1330
+ 'edit_label' => __( 'Edit', 'co-authors-plus' ),
1331
+ 'delete_label' => __( 'Remove', 'co-authors-plus' ),
1332
+ 'confirm_delete' => __( 'Are you sure you want to remove this author?', 'co-authors-plus' ),
1333
  'input_box_title' => __( 'Click to change this author, or drag to change their position', 'co-authors-plus' ),
1334
  'search_box_text' => __( 'Search for an author', 'co-authors-plus' ),
1335
+ 'help_text' => __( 'Click on an author to change them. Drag to change their order. Click on <strong>Remove</strong> to remove them.', 'co-authors-plus' ),
1336
+ );
1337
  wp_localize_script( 'co-authors-plus-js', 'coAuthorsPlusStrings', $js_strings );
1338
 
1339
  }
1360
  return $views;
1361
  }
1362
 
1363
+ $views = array_reverse( $views );
1364
+ $all_view = array_pop( $views );
1365
  $mine_args = array(
1366
+ 'author_name' => wp_get_current_user()->user_nicename,
1367
+ );
1368
  if ( 'post' != get_post_type() ) {
1369
  $mine_args['post_type'] = get_current_screen()->post_type;
1370
  }
1376
  $views['mine'] = $view_mine = '<a' . $class . ' href="' . esc_url( add_query_arg( array_map( 'rawurlencode', $mine_args ), admin_url( 'edit.php' ) ) ) . '">' . __( 'Mine', 'co-authors-plus' ) . '</a>';
1377
 
1378
  $views['all'] = str_replace( $class, '', $all_view );
1379
+ $views = array_reverse( $views );
1380
 
1381
  return $views;
1382
  }
1386
  */
1387
  public function js_vars() {
1388
 
1389
+ if ( ! $this->is_valid_page() || ! $this->is_post_type_enabled() || ! $this->current_user_can_set_authors() ) {
1390
  return;
1391
  }
1392
  ?>
1393
  <script type="text/javascript">
1394
  // AJAX link used for the autosuggest
1395
+ var coAuthorsPlus_ajax_suggest_link =
1396
+ <?php
1397
  echo wp_json_encode(
1398
  add_query_arg(
1399
  array(
1400
+ 'action' => 'coauthors_ajax_suggest',
1401
  'post_type' => rawurlencode( get_post_type() ),
1402
  ),
1403
  wp_nonce_url( 'admin-ajax.php', 'coauthors-search' )
1404
  )
1405
+ );
1406
+ ?>
1407
+ ;
1408
  </script>
1409
  <?php
1410
  }
1430
  * @return array caps that CAP should filter
1431
  */
1432
  public function get_to_be_filtered_caps() {
1433
+ if ( ! empty( $this->supported_post_types ) && empty( $this->to_be_filtered_caps ) ) {
1434
  $this->to_be_filtered_caps[] = 'edit_post'; // Need to filter this too, unfortunately: http://core.trac.wordpress.org/ticket/22415
1435
  $this->to_be_filtered_caps[] = 'read_post';
1436
 
1437
+ foreach ( $this->supported_post_types as $single ) {
1438
  $obj = get_post_type_object( $single );
1439
 
1440
  $this->to_be_filtered_caps[] = $obj->cap->edit_post;
1453
  */
1454
  function filter_user_has_cap( $allcaps, $caps, $args ) {
1455
 
1456
+ $cap = $args[0];
1457
  $user_id = isset( $args[1] ) ? $args[1] : 0;
1458
  $post_id = isset( $args[2] ) ? $args[2] : 0;
1459
 
1460
+ if ( ! in_array( $cap, $this->get_to_be_filtered_caps(), true ) ) {
1461
  return $allcaps;
1462
  }
1463
 
1466
  return $allcaps;
1467
  }
1468
 
1469
+ // Even though we bail if cap is not among the to_be_filtered ones, there is a time in early request processing in which that list is not yet available, so the following block is needed
1470
  $caps_to_modify = array(
1471
+ $obj->cap->edit_post,
1472
+ 'edit_post', // Need to filter this too, unfortunately: http://core.trac.wordpress.org/ticket/22415
1473
+ $obj->cap->edit_others_posts, // This as well: http://core.trac.wordpress.org/ticket/22417
1474
+ 'read_post',
1475
+ $obj->cap->read_post,
1476
+ );
1477
  if ( ! in_array( $cap, $caps_to_modify ) ) {
1478
  return $allcaps;
1479
  }
1552
  }
1553
  } else {
1554
  $coauthor_slug = 'cap-' . $coauthor->user_nicename;
1555
+ $args = array(
1556
+ 'slug' => $coauthor_slug,
1557
+ 'description' => $term_description,
1558
  );
1559
 
1560
  $new_term = wp_insert_term( $coauthor->user_login, $this->coauthor_taxonomy, $args );
1569
  * @see https://github.com/Automattic/Co-Authors-Plus/issues/2
1570
  *
1571
  * @param array $information_fields
1572
+ * @param int $post_id
1573
  * @return array
1574
  */
1575
  function filter_ef_calendar_item_information_fields( $information_fields, $post_id ) {
1581
 
1582
  $co_authors = get_coauthors( $post_id );
1583
  if ( count( $co_authors ) > 1 ) {
1584
+ $information_fields[ $this->coauthor_taxonomy ]['label'] = __( 'Authors', 'co-authors-plus' );
1585
  }
1586
  $co_authors_names = '';
1587
  foreach ( $co_authors as $co_author ) {
1588
  $co_authors_names .= $co_author->display_name . ', ';
1589
  }
1590
+ $information_fields[ $this->coauthor_taxonomy ]['value'] = rtrim( $co_authors_names, ', ' );
1591
  return $information_fields;
1592
  }
1593
 
1608
  return $column_name;
1609
  }
1610
 
1611
+ $co_authors = get_coauthors( $post->ID );
1612
  $co_authors_names = '';
1613
  foreach ( $co_authors as $co_author ) {
1614
  $co_authors_names .= $co_author->display_name . ', ';
1628
  public function filter_jetpack_open_graph_tags( $og_tags, $image_dimensions ) {
1629
 
1630
  if ( is_author() ) {
1631
+ $author = get_queried_object();
1632
  $og_tags['og:title'] = $author->display_name;
1633
  $og_tags['og:url'] = get_author_posts_url( $author->ID, $author->user_nicename );
1634
  $og_tags['og:description'] = $author->description;
1637
  if ( isset( $og_tags['article:author'] ) ) {
1638
  $og_tags['article:author'] = get_author_posts_url( $author->ID, $author->user_nicename );
1639
  }
1640
+ } elseif ( is_singular() && $this->is_post_type_enabled() ) {
1641
  $authors = get_coauthors();
1642
  if ( ! empty( $authors ) ) {
1643
  $author = array_shift( $authors );
1666
  return array();
1667
  }
1668
 
1669
+ $cache_key = 'coauthors_post_' . $post_id;
1670
  $coauthor_terms = wp_cache_get( $cache_key, 'co-authors-plus' );
1671
 
1672
  if ( false === $coauthor_terms ) {
1673
+ $coauthor_terms = wp_get_object_terms(
1674
+ $post_id,
1675
+ $this->coauthor_taxonomy,
1676
+ array(
1677
+ 'orderby' => 'term_order',
1678
+ 'order' => 'ASC',
1679
+ )
1680
+ );
1681
 
1682
  // This usually happens if the taxonomy doesn't exist, which should never happen, but you never know.
1683
  if ( is_wp_error( $coauthor_terms ) ) {
1731
  }
1732
 
1733
  $author_slug = sanitize_user( get_query_var( 'author_name' ) );
1734
+ $author = $this->get_coauthor_by( 'user_nicename', $author_slug );
1735
 
1736
  return sprintf( __( 'Author: %s' ), $author->display_name );
1737
  }
1755
  && $guest_term->count ) {
1756
  $user = get_user_by( 'login', $guest_author->linked_account );
1757
  if ( is_object( $user ) ) {
1758
+ return count_user_posts( $user->ID ); // phpcs:ignore
1759
  }
1760
  } elseif ( $term ) {
1761
  return $term->count;
1777
  return $args;
1778
  }
1779
  $coauthor = $this->get_coauthor_by( 'id', $id );
1780
+ if ( false !== $coauthor && isset( $coauthor->type ) && 'guest-author' === $coauthor->type ) {
1781
  if ( has_post_thumbnail( $id ) ) {
1782
  $args['url'] = get_the_post_thumbnail_url( $id, $this->gravatar_size );
1783
+ } elseif ( isset( $coauthor->user_email ) ) {
1784
+ $args['url'] = get_avatar_url( $coauthor->user_email );
1785
  } else {
1786
  $args['url'] = get_avatar_url( '' ); // Fallback to default.
1787
  }
1801
  *
1802
  * @since 2.6.2
1803
  *
1804
+ * @param int $comment_id Comment ID
1805
  * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback'
1806
  * @return bool False if user email does not exist. True on completion.
1807
  */
1808
  function wp_notify_postauthor( $comment_id, $comment_type = '' ) {
1809
+ $comment = get_comment( $comment_id );
1810
+ $post = get_post( $comment->comment_post_ID );
1811
  $coauthors = get_coauthors( $post->ID );
1812
  foreach ( $coauthors as $author ) {
1813
 
1837
  }
1838
 
1839
  if ( 'comment' == $comment_type ) {
1840
+ $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n";
1841
  /* translators: 1: comment author, 2: author IP, 3: author domain */
1842
  $notify_message .= sprintf( __( 'Author : %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1843
  $notify_message .= sprintf( __( 'E-mail : %s' ), $comment->comment_author_email ) . "\r\n";
1848
  /* translators: 1: blog name, 2: post title */
1849
  $subject = sprintf( __( '[%1$s] Comment: "%2$s"' ), $blogname, $post->post_title );
1850
  } elseif ( 'trackback' == $comment_type ) {
1851
+ $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n";
1852
  /* translators: 1: website name, 2: author IP, 3: author domain */
1853
  $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1854
  $notify_message .= sprintf( __( 'URL : %s' ), $comment->comment_author_url ) . "\r\n";
1857
  /* translators: 1: blog name, 2: post title */
1858
  $subject = sprintf( __( '[%1$s] Trackback: "%2$s"' ), $blogname, $post->post_title );
1859
  } elseif ( 'pingback' == $comment_type ) {
1860
+ $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n";
1861
  /* translators: 1: comment author, 2: author IP, 3: author domain */
1862
  $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s , %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
1863
  $notify_message .= sprintf( __( 'URL : %s' ), $comment->comment_author_url ) . "\r\n";
1875
  }
1876
  $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c=$comment_id" ) ) . "\r\n";
1877
 
1878
+ $wp_email = 'wordpress@' . preg_replace( '#^www\.#', '', strtolower( $_SERVER['SERVER_NAME'] ) ); // phpcs:ignore
1879
 
1880
  if ( '' == $comment->comment_author ) {
1881
  $from = "From: \"$blogname\" <$wp_email>";
1896
  $message_headers .= $reply_to . "\n";
1897
  }
1898
 
1899
+ $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment_id );
1900
+ $subject = apply_filters( 'comment_notification_subject', $subject, $comment_id );
1901
  $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment_id );
1902
 
1903
  @wp_mail( $author->user_email, $subject, $notify_message, $message_headers );
1911
  * Filter array of moderation notification email addresses
1912
  *
1913
  * @param array $recipients
1914
+ * @param int $comment_id
1915
  * @return array
1916
  */
1917
  function cap_filter_comment_moderation_email_recipients( $recipients, $comment_id ) {
1919
  $post_id = $comment->comment_post_ID;
1920
 
1921
  if ( isset( $post_id ) ) {
1922
+ $coauthors = get_coauthors( $post_id );
1923
  $extra_recipients = array();
1924
  foreach ( $coauthors as $user ) {
1925
  if ( ! empty( $user->user_email ) ) {
1944
  function cap_get_coauthor_terms_for_post( $post_id ) {
1945
  global $coauthors_plus;
1946
  return $coauthors_plus->get_coauthor_terms_for_post( $post_id );
1947
+ }
composer.json CHANGED
@@ -1,27 +1,62 @@
1
  {
2
- "name" : "automattic/co-authors-plus",
3
- "description": "Multiple bylines and Guest Authors for WordPress",
4
- "homepage" : "http://wordpress.org/plugins/co-authors-plus/",
5
- "type" : "wordpress-plugin",
6
- "license" : "GPL-2.0+",
7
- "authors" : [
8
- {
9
- "name": "Daniel Bachhuber",
10
- "email": "d@danielbachhuber.com",
11
- "homepage": "http://danielbachhuber.com",
12
- "role": "Developer"
13
- },
14
- {
15
- "name" : "Automattic",
16
- "homepage": "http://automattic.com/"
17
- }
18
- ],
19
- "support" : {
20
- "issues": "https://github.com/Automattic/Co-Authors-Plus/issues",
21
- "source": "https://github.com/Automattic/Co-Authors-Plus",
22
- "forum": "http://wordpress.org/support/plugin/co-authors-plus"
23
- },
24
- "require": {
25
- "composer/installers": "~1.0"
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
1
  {
2
+ "name": "automattic/co-authors-plus",
3
+ "description": "Multiple bylines and Guest Authors for WordPress",
4
+ "homepage": "http://wordpress.org/plugins/co-authors-plus/",
5
+ "type": "wordpress-plugin",
6
+ "license": "GPL-2.0+",
7
+ "authors": [
8
+ {
9
+ "name": "Daniel Bachhuber",
10
+ "email": "d@danielbachhuber.com",
11
+ "homepage": "http://danielbachhuber.com",
12
+ "role": "Developer"
13
+ },
14
+ {
15
+ "name": "Automattic",
16
+ "homepage": "http://automattic.com/"
17
+ }
18
+ ],
19
+ "support": {
20
+ "issues": "https://github.com/Automattic/Co-Authors-Plus/issues",
21
+ "source": "https://github.com/Automattic/Co-Authors-Plus",
22
+ "forum": "http://wordpress.org/support/plugin/co-authors-plus"
23
+ },
24
+ "require": {
25
+ "composer/installers": "~1.0",
26
+ "php": ">=5.6"
27
+ },
28
+ "require-dev": {
29
+ "automattic/vipwpcs": "^2.2",
30
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7",
31
+ "php-parallel-lint/php-parallel-lint": "^1.0",
32
+ "phpcompatibility/phpcompatibility-wp": "^2.1",
33
+ "phpunit/phpunit": "^4 || ^5 || ^6 || ^7",
34
+ "squizlabs/php_codesniffer": "^3.5",
35
+ "wp-coding-standards/wpcs": "^2.3.0",
36
+ "yoast/phpunit-polyfills": "^0.2.0"
37
+ },
38
+ "scripts": {
39
+ "cs": [
40
+ "@php ./vendor/bin/phpcs -p -s -v -n . --standard=\"WordPress-VIP-Go\" --extensions=php --ignore=\"/vendor/*,/node_modules/*,/tests/*\""
41
+ ],
42
+ "cbf": [
43
+ "@php ./vendor/bin/phpcbf -p -s -v -n . --standard=\"WordPress-VIP-Go\" --extensions=php --ignore=\"/vendor/*,/node_modules/*,/tests/*\""
44
+ ],
45
+ "lint": [
46
+ "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git"
47
+ ],
48
+ "lint-ci": [
49
+ "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git --checkstyle"
50
+ ],
51
+ "prepare": [
52
+ "bash bin/install-wp-tests.sh wordpress_test root root localhost"
53
+ ],
54
+ "integration": [
55
+ "@php ./vendor/bin/phpunit --testsuite WP_Tests"
56
+ ],
57
+ "integration-ms": [
58
+ "@putenv WP_MULTISITE=1",
59
+ "@composer integration"
60
+ ]
61
+ }
62
  }
css/co-authors-plus.css CHANGED
@@ -112,6 +112,7 @@
112
 
113
  /** Block Editor Hack for 5.0: Hide the core author input **/
114
  .block-editor label[for^="post-author-selector-"],
115
- .block-editor select[id^="post-author-selector-"] {
 
116
  display: none;
117
  }
112
 
113
  /** Block Editor Hack for 5.0: Hide the core author input **/
114
  .block-editor label[for^="post-author-selector-"],
115
+ .block-editor select[id^="post-author-selector-"],
116
+ .block-editor .post-author-selector {
117
  display: none;
118
  }
js/co-authors-plus.js CHANGED
@@ -193,7 +193,7 @@ jQuery( document ).ready(function () {
193
  // Callback for when a user selects a co-author
194
  function coauthors_autosuggest_select() {
195
  $this = jQuery( this );
196
- var vals = this.value.split( '|' );
197
 
198
  var author = {}
199
  author.id = jQuery.trim( vals[0] );
@@ -424,7 +424,7 @@ jQuery( document ).ready(function () {
424
  avatar: jQuery( el ).data( 'avatar' ),
425
  }
426
  });
427
-
428
  coauthors_initialize( post_coauthors );
429
 
430
  }
193
  // Callback for when a user selects a co-author
194
  function coauthors_autosuggest_select() {
195
  $this = jQuery( this );
196
+ var vals = this.value.split( '' );
197
 
198
  var author = {}
199
  author.id = jQuery.trim( vals[0] );
424
  avatar: jQuery( el ).data( 'avatar' ),
425
  }
426
  });
427
+
428
  coauthors_initialize( post_coauthors );
429
 
430
  }
languages/co-authors-plus-he_IL.mo ADDED
Binary file
languages/co-authors-plus-he_IL.po ADDED
@@ -0,0 +1,593 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2014 Co-Authors Plus
2
+ # This file is distributed under the same license as the Co-Authors Plus package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Co-Authors Plus 3.1-beta\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/co-authors-plus\n"
7
+ "POT-Creation-Date: 2014-03-17 15:59:18+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2019-01-07 16:19+0200\n"
12
+ "Language-Team: \n"
13
+ "X-Generator: Poedit 2.1.1\n"
14
+ "Last-Translator: \n"
15
+ "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? "
16
+ "2 : 3);\n"
17
+ "Language: he_IL\n"
18
+
19
+ #: co-authors-plus.php:300 co-authors-plus.php:401 co-authors-plus.php:487
20
+ #: co-authors-plus.php:1290
21
+ msgid "Authors"
22
+ msgstr "מחברים"
23
+
24
+ #: co-authors-plus.php:362
25
+ msgid ""
26
+ "<strong>Note:</strong> To edit post authors, please enable javascript or use "
27
+ "a javascript-capable browser"
28
+ msgstr ""
29
+ "<strong>שימו לב:</strong> כדי לערוך את מחברי הפוסט יש לאפשר שימוש "
30
+ "Javascript בדפדפן."
31
+
32
+ #: co-authors-plus.php:369 co-authors-plus.php:489 co-authors-plus.php:1095
33
+ msgid ""
34
+ "Click on an author to change them. Drag to change their order. Click on "
35
+ "<strong>Remove</strong> to remove them."
36
+ msgstr ""
37
+ "לחצו על מחבר כדי לשנות אותו. גררו מחברים כדי לשנות את הסדר שלהם. לחצו על "
38
+ "<strong>הסרה</strong> כדי למחוק אותם."
39
+
40
+ #: co-authors-plus.php:449 php/class-coauthors-wp-list-table.php:148
41
+ msgid "Posts"
42
+ msgstr "פוסטים"
43
+
44
+ #: co-authors-plus.php:466
45
+ msgid "View posts by this author"
46
+ msgstr "הצגת פוסטים לפי מחבר"
47
+
48
+ #: co-authors-plus.php:531 co-authors-plus.php:548
49
+ msgid "No co-author exists for that term"
50
+ msgstr "לא נמצאו מחברים"
51
+
52
+ #: co-authors-plus.php:1090 php/class-coauthors-wp-list-table.php:212
53
+ msgid "Edit"
54
+ msgstr "עריכה"
55
+
56
+ #: co-authors-plus.php:1091
57
+ msgid "Remove"
58
+ msgstr "הסרה"
59
+
60
+ #: co-authors-plus.php:1092
61
+ msgid "Are you sure you want to remove this author?"
62
+ msgstr "האם באמת להסיר את המחבר הזה?"
63
+
64
+ #: co-authors-plus.php:1093
65
+ msgid "Click to change this author, or drag to change their position"
66
+ msgstr "לחצו לעריכת המחבר, או גררו לשינוי המיקום שלו"
67
+
68
+ #: co-authors-plus.php:1094
69
+ msgid "Search for an author"
70
+ msgstr "חיפוש מחברים"
71
+
72
+ #: co-authors-plus.php:1132
73
+ msgid "Mine"
74
+ msgstr "שלי"
75
+
76
+ #: co-authors-plus.php:1402
77
+ msgid "New comment on your post \"%s\""
78
+ msgstr "תגובות חדשות על הפוסט שלך \"%s\""
79
+
80
+ #. translators: 1: comment author, 2: author IP, 3: author domain
81
+ #: co-authors-plus.php:1404 co-authors-plus.php:1521
82
+ msgid "Author : %1$s (IP: %2$s , %3$s)"
83
+ msgstr "מחבר : %1$s (IP: %2$s , %3$s)"
84
+
85
+ #: co-authors-plus.php:1405 co-authors-plus.php:1522
86
+ msgid "E-mail : %s"
87
+ msgstr "אימייל: %s"
88
+
89
+ #: co-authors-plus.php:1406 co-authors-plus.php:1416 co-authors-plus.php:1425
90
+ #: co-authors-plus.php:1508 co-authors-plus.php:1515 co-authors-plus.php:1523
91
+ msgid "URL : %s"
92
+ msgstr "כתובת URL: %s"
93
+
94
+ #: co-authors-plus.php:1407 co-authors-plus.php:1524
95
+ msgid "Whois : http://whois.arin.net/rest/ip/%s"
96
+ msgstr ""
97
+
98
+ #: co-authors-plus.php:1408 co-authors-plus.php:1525
99
+ msgid "Comment: "
100
+ msgstr "תגובה:"
101
+
102
+ #: co-authors-plus.php:1409
103
+ msgid "You can see all comments on this post here: "
104
+ msgstr "כאן ניתן לראות את כל התגובות לפוסט זה:"
105
+
106
+ #. translators: 1: blog name, 2: post title
107
+ #: co-authors-plus.php:1411
108
+ msgid "[%1$s] Comment: \"%2$s\""
109
+ msgstr "[%1$s] תגובות: \"%2$s\""
110
+
111
+ #: co-authors-plus.php:1413
112
+ msgid "New trackback on your post \"%s\""
113
+ msgstr "טראקבקים חדשים על הפוסט שלך \" %s\""
114
+
115
+ #. translators: 1: website name, 2: author IP, 3: author domain
116
+ #. translators: 1: comment author, 2: author IP, 3: author domain
117
+ #: co-authors-plus.php:1415 co-authors-plus.php:1424
118
+ msgid "Website: %1$s (IP: %2$s , %3$s)"
119
+ msgstr "אתר:%1$s (IP:%2$s,%3$s)"
120
+
121
+ #: co-authors-plus.php:1417 co-authors-plus.php:1426
122
+ msgid "Excerpt: "
123
+ msgstr "תקציר:"
124
+
125
+ #: co-authors-plus.php:1418
126
+ msgid "You can see all trackbacks on this post here: "
127
+ msgstr "כאן ניתן לראות את כל הטראקבקים לפוסט זה:"
128
+
129
+ #. translators: 1: blog name, 2: post title
130
+ #: co-authors-plus.php:1420
131
+ msgid "[%1$s] Trackback: \"%2$s\""
132
+ msgstr "[%1$s] טראקבקים: \"%2$s\""
133
+
134
+ #: co-authors-plus.php:1422
135
+ msgid "New pingback on your post \"%s\""
136
+ msgstr "פינגבק חדש בפוסט שלך \" %s\""
137
+
138
+ #: co-authors-plus.php:1427
139
+ msgid "You can see all pingbacks on this post here: "
140
+ msgstr "כאן ניתן לראות את כל הפינגבקים לפוסט זה:"
141
+
142
+ #. translators: 1: blog name, 2: post title
143
+ #: co-authors-plus.php:1429
144
+ msgid "[%1$s] Pingback: \"%2$s\""
145
+ msgstr "[%1$s] פינגבקים: \"%2$s\""
146
+
147
+ #: co-authors-plus.php:1432
148
+ msgid "Permalink: %s"
149
+ msgstr "קישור: %s"
150
+
151
+ #: co-authors-plus.php:1434 co-authors-plus.php:1531
152
+ msgid "Trash it: %s"
153
+ msgstr "אשפה: %s"
154
+
155
+ #: co-authors-plus.php:1436 co-authors-plus.php:1533
156
+ msgid "Delete it: %s"
157
+ msgstr "מחיקה: %s"
158
+
159
+ #: co-authors-plus.php:1437 co-authors-plus.php:1534
160
+ msgid "Spam it: %s"
161
+ msgstr "ספאם: %s"
162
+
163
+ #: co-authors-plus.php:1505
164
+ msgid "A new trackback on the post \"%s\" is waiting for your approval"
165
+ msgstr "טראקבק חדש על הפוסט \"%s\" מחכה לאישורך"
166
+
167
+ #: co-authors-plus.php:1507 co-authors-plus.php:1514
168
+ msgid "Website : %1$s (IP: %2$s , %3$s)"
169
+ msgstr "אתר : %1$s (IP: %2$s , %3$s)"
170
+
171
+ #: co-authors-plus.php:1509
172
+ msgid "Trackback excerpt: "
173
+ msgstr "תקציר הטראקבק:"
174
+
175
+ #: co-authors-plus.php:1512
176
+ msgid "A new pingback on the post \"%s\" is waiting for your approval"
177
+ msgstr "פינגבק חדש על הפוסט \"%s\" מחכה לאישורך"
178
+
179
+ #: co-authors-plus.php:1516
180
+ msgid "Pingback excerpt: "
181
+ msgstr "תקציר הפינגבק:"
182
+
183
+ #: co-authors-plus.php:1519
184
+ msgid "A new comment on the post \"%s\" is waiting for your approval"
185
+ msgstr "תגובה חדשה על הפוסט \"%s\" מחכה לאישורך"
186
+
187
+ #: co-authors-plus.php:1529
188
+ msgid "Approve it: %s"
189
+ msgstr "אישור: %s"
190
+
191
+ #: co-authors-plus.php:1536
192
+ msgid ""
193
+ "Currently %s comment is waiting for approval. Please visit the moderation "
194
+ "panel:"
195
+ msgid_plural ""
196
+ "Currently %s comments are waiting for approval. Please visit the moderation "
197
+ "panel:"
198
+ msgstr[0] "ישנה תגובה אחת המחכה לאישורך. עברו לפאנל הניהול:"
199
+ msgstr[1] "ישנן %s תגובות המחכות לאישורך. עברו לפאנל הניהול:"
200
+ msgstr[2] ""
201
+ msgstr[3] ""
202
+
203
+ #: co-authors-plus.php:1540
204
+ msgid "[%1$s] Please moderate: \"%2$s\""
205
+ msgstr "[%1$s] נא לבדוק ולאשר: \"%2$s\""
206
+
207
+ #: php/class-coauthors-guest-authors.php:80
208
+ msgid "Guest Author"
209
+ msgstr "מחבר אורח"
210
+
211
+ #: php/class-coauthors-guest-authors.php:81
212
+ msgid "Guest Authors"
213
+ msgstr "מחברים אורחים"
214
+
215
+ #: php/class-coauthors-guest-authors.php:82
216
+ msgid "All Guest Authors"
217
+ msgstr "כל המחברים האורחים"
218
+
219
+ #: php/class-coauthors-guest-authors.php:83
220
+ msgid "Add New Guest Author"
221
+ msgstr "הוספת מחבר אורח"
222
+
223
+ #: php/class-coauthors-guest-authors.php:84
224
+ msgid "Edit Guest Author"
225
+ msgstr "עריכת מחבר אורח"
226
+
227
+ #: php/class-coauthors-guest-authors.php:85
228
+ msgid "New Guest Author"
229
+ msgstr "מחבר אורח חדש"
230
+
231
+ #: php/class-coauthors-guest-authors.php:86
232
+ msgid "View Guest Author"
233
+ msgstr "צפיה במחבר אורח"
234
+
235
+ #: php/class-coauthors-guest-authors.php:87
236
+ msgid "Search Guest Authors"
237
+ msgstr "חיפוש מחברים אורחים"
238
+
239
+ #: php/class-coauthors-guest-authors.php:88
240
+ msgid "No guest authors found"
241
+ msgstr "לא נמצאו מחברים אורחים"
242
+
243
+ #: php/class-coauthors-guest-authors.php:89
244
+ msgid "No guest authors found in Trash"
245
+ msgstr "לא נמצאו מחברים אורחים באשפה"
246
+
247
+ #: php/class-coauthors-guest-authors.php:90
248
+ msgid "Update Guest Author"
249
+ msgstr "עדכון מחבר אורח"
250
+
251
+ #: php/class-coauthors-guest-authors.php:91
252
+ msgid "About the guest author"
253
+ msgstr "אודות המחבר"
254
+
255
+ #: php/class-coauthors-guest-authors.php:100
256
+ msgctxt "guest author"
257
+ msgid "Add New"
258
+ msgstr "חדש"
259
+
260
+ #: php/class-coauthors-guest-authors.php:156
261
+ #: php/class-coauthors-guest-authors.php:162
262
+ msgid "Guest author updated. <a href=\"%s\">View profile</a>"
263
+ msgstr "מחבר אורח עודכן בהצלחה. <a href=\"%s\">צפייה בפרופיל</a>"
264
+
265
+ #: php/class-coauthors-guest-authors.php:157
266
+ msgid "Custom field updated."
267
+ msgstr "שדה מותאם עודכן בהצלחה."
268
+
269
+ #: php/class-coauthors-guest-authors.php:158
270
+ msgid "Custom field deleted."
271
+ msgstr "שדה מותאם נמחק."
272
+
273
+ #: php/class-coauthors-guest-authors.php:159
274
+ msgid "Guest author updated."
275
+ msgstr "מחבר אורח עודכן בהצלחה."
276
+
277
+ #. translators: %s: date and time of the revision
278
+ #: php/class-coauthors-guest-authors.php:161
279
+ msgid "Guest author restored to revision from %s"
280
+ msgstr "מחבר אורח שיחזר לעותק שמור מ-%s"
281
+
282
+ #: php/class-coauthors-guest-authors.php:163
283
+ msgid "Guest author saved."
284
+ msgstr "מחבר אורח נשמר."
285
+
286
+ #: php/class-coauthors-guest-authors.php:164
287
+ msgid ""
288
+ "Guest author submitted. <a target=\"_blank\" href=\"%s\">Preview profile</a>"
289
+ msgstr "מחבר אורח נשמר. <a target=\"_blank\" href=\"%s\">תצוגה מקדימה</a>"
290
+
291
+ #: php/class-coauthors-guest-authors.php:165
292
+ msgid ""
293
+ "Guest author scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href="
294
+ "\"%2$s\">Preview profile</a>"
295
+ msgstr ""
296
+ "מחבר אורח מתוזמן ל: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s"
297
+ "\">תצוגה מקדימה</a>"
298
+
299
+ #. translators: Publish box date format, see http:php.net/date
300
+ #: php/class-coauthors-guest-authors.php:167
301
+ msgid "M j, Y @ G:i"
302
+ msgstr ""
303
+
304
+ #: php/class-coauthors-guest-authors.php:168
305
+ msgid ""
306
+ "Guest author updated. <a target=\"_blank\" href=\"%s\">Preview profile</a>"
307
+ msgstr "מחבר אורח עודכן. <a target=\"_blank\" href=\"%s\">תצוגה מקדימה</a>"
308
+
309
+ #: php/class-coauthors-guest-authors.php:185
310
+ #: php/class-coauthors-guest-authors.php:218
311
+ #: php/class-coauthors-guest-authors.php:437
312
+ msgid "Doin' something fishy, huh?"
313
+ msgstr "מה אתה זומם הא?"
314
+
315
+ #: php/class-coauthors-guest-authors.php:188
316
+ #: php/class-coauthors-guest-authors.php:222
317
+ msgid "You don't have permission to perform this action."
318
+ msgstr "אין לך הרשאה לבצע פעולה זו."
319
+
320
+ #: php/class-coauthors-guest-authors.php:227
321
+ #: php/class-coauthors-guest-authors.php:442
322
+ msgid "Guest author can't be deleted because it doesn't exist."
323
+ msgstr "המחבר-אורח לא קיים ולכן לא ניתן למחוק אותו."
324
+
325
+ #: php/class-coauthors-guest-authors.php:241
326
+ msgid "Co-author does not exists. Try again?"
327
+ msgstr "מחבר-אורח לא קיים. לנסות שוב?"
328
+
329
+ #: php/class-coauthors-guest-authors.php:249
330
+ msgid "Please make sure to pick an option."
331
+ msgstr "נא לבחור אפשרות."
332
+
333
+ #: php/class-coauthors-guest-authors.php:393
334
+ msgid "Guest author deleted."
335
+ msgstr "מחבר-אורח נמחק."
336
+
337
+ #: php/class-coauthors-guest-authors.php:417
338
+ msgid "Save"
339
+ msgstr "שמירה"
340
+
341
+ #: php/class-coauthors-guest-authors.php:418
342
+ msgid "Unique Slug"
343
+ msgstr "כינוי ייחודי"
344
+
345
+ #: php/class-coauthors-guest-authors.php:420
346
+ msgid "Name"
347
+ msgstr "שם"
348
+
349
+ #: php/class-coauthors-guest-authors.php:421
350
+ msgid "Contact Info"
351
+ msgstr "יצירת קשר"
352
+
353
+ #: php/class-coauthors-guest-authors.php:446
354
+ msgid "Delete %s"
355
+ msgstr "מחיקת %s"
356
+
357
+ #: php/class-coauthors-guest-authors.php:447
358
+ msgid "You have specified this guest author for deletion:"
359
+ msgstr "המחבר האורח הבא מיועד למחיקה:"
360
+
361
+ #: php/class-coauthors-guest-authors.php:449
362
+ msgid "What should be done with posts assigned to this guest author?"
363
+ msgstr "מה לעשות עם פוסטים המשוייכים למחבר-אורח הזה?"
364
+
365
+ #: php/class-coauthors-guest-authors.php:450
366
+ msgid ""
367
+ "Note: If you'd like to delete the guest author and all of their posts, you "
368
+ "should delete their posts first and then come back to delete the guest "
369
+ "author."
370
+ msgstr ""
371
+ "שימו לב: על מנת למחוק את המחבר-אורח וכל הפוסטים שלו, יש קודם כל למחוק את כל "
372
+ "הפוסטים שלו, ואז לחזור לכן ולמחוק את המחבר-אורח"
373
+
374
+ #: php/class-coauthors-guest-authors.php:459
375
+ msgid "Reassign to another co-author:"
376
+ msgstr "שיוך למחבר-אורח אחר:"
377
+
378
+ #: php/class-coauthors-guest-authors.php:465
379
+ msgid "Leave posts assigned to the mapped user, %s."
380
+ msgstr "השאר פוסטים משוייכים למשתמש מקושר, %s"
381
+
382
+ #: php/class-coauthors-guest-authors.php:470
383
+ msgid "Remove byline from posts (but leave each post in its current status)."
384
+ msgstr "הסרת שותפויות מהפוסט (הפוסט ישמור על הסטטוס שלו)"
385
+
386
+ #: php/class-coauthors-guest-authors.php:473
387
+ msgid "Confirm Deletion"
388
+ msgstr "אישור מחיקה"
389
+
390
+ #: php/class-coauthors-guest-authors.php:482
391
+ msgid "Add New"
392
+ msgstr "חדש"
393
+
394
+ #: php/class-coauthors-guest-authors.php:543
395
+ msgid "WordPress User Mapping"
396
+ msgstr "קישור משתמשים"
397
+
398
+ #: php/class-coauthors-guest-authors.php:545
399
+ msgid "-- Not mapped --"
400
+ msgstr "-- לא מקושר --"
401
+
402
+ #: php/class-coauthors-guest-authors.php:679
403
+ #: php/class-coauthors-guest-authors.php:688
404
+ msgid "Guest authors cannot be created without display names."
405
+ msgstr "מחבר-אורח לא יכול להיות ללא שם תצוגה."
406
+
407
+ #: php/class-coauthors-guest-authors.php:697
408
+ msgid ""
409
+ "Guest authors cannot be created with the same user_login value as a user. "
410
+ "Try creating a profile from the user on the Manage Users listing instead."
411
+ msgstr ""
412
+ "מחבר-אורח לא יכול להיות עם אותו כינוי ייחודי כמו משתמש אמיתי. אפשר במקום זה "
413
+ "ליצור פרופיל חדש בניהול המשתמשים. "
414
+
415
+ #: php/class-coauthors-guest-authors.php:702
416
+ msgid "Display name conflicts with another guest author display name."
417
+ msgstr "שם תצוגה מתנגש עם שם תצוגה של מחבר-אורח אחר."
418
+
419
+ #: php/class-coauthors-guest-authors.php:896
420
+ msgid "ID"
421
+ msgstr ""
422
+
423
+ #: php/class-coauthors-guest-authors.php:903
424
+ #: php/class-coauthors-wp-list-table.php:143
425
+ msgid "Display Name"
426
+ msgstr "שם תצוגה"
427
+
428
+ #: php/class-coauthors-guest-authors.php:909
429
+ #: php/class-coauthors-wp-list-table.php:144
430
+ msgid "First Name"
431
+ msgstr "שם פרטי"
432
+
433
+ #: php/class-coauthors-guest-authors.php:914
434
+ #: php/class-coauthors-wp-list-table.php:145
435
+ msgid "Last Name"
436
+ msgstr "שם משפחה"
437
+
438
+ #: php/class-coauthors-guest-authors.php:919
439
+ msgid "Slug"
440
+ msgstr "כינוי ייחודי (slug)"
441
+
442
+ #: php/class-coauthors-guest-authors.php:926
443
+ #: php/class-coauthors-wp-list-table.php:146
444
+ msgid "E-mail"
445
+ msgstr "דוא\\\"ל"
446
+
447
+ #: php/class-coauthors-guest-authors.php:932
448
+ #: php/class-coauthors-wp-list-table.php:147
449
+ msgid "Linked Account"
450
+ msgstr "חשבון מקושר"
451
+
452
+ #: php/class-coauthors-guest-authors.php:937
453
+ msgid "Website"
454
+ msgstr "אתר"
455
+
456
+ #: php/class-coauthors-guest-authors.php:943
457
+ msgid "AIM"
458
+ msgstr ""
459
+
460
+ #: php/class-coauthors-guest-authors.php:948
461
+ msgid "Yahoo IM"
462
+ msgstr ""
463
+
464
+ #: php/class-coauthors-guest-authors.php:953
465
+ msgid "Jabber / Google Talk"
466
+ msgstr ""
467
+
468
+ #: php/class-coauthors-guest-authors.php:958
469
+ msgid "Biographical Info"
470
+ msgstr "מידע ביוגרפי"
471
+
472
+ #: php/class-coauthors-guest-authors.php:1122
473
+ msgid "%s is a required field"
474
+ msgstr "%s הוא שדה חובה."
475
+
476
+ #: php/class-coauthors-guest-authors.php:1128
477
+ msgid "user_login cannot duplicate existing guest author or mapped user"
478
+ msgstr ""
479
+ "כינוי חייב להיות ייחודי ולא להיות זהה לשם-משתמש שקושר או למחבר-אורח אחר."
480
+
481
+ #: php/class-coauthors-guest-authors.php:1173
482
+ msgid "Guest author does not exist"
483
+ msgstr "מחבר אורח לא קיים"
484
+
485
+ #: php/class-coauthors-guest-authors.php:1185
486
+ msgid "Reassignment co-author does not exist"
487
+ msgstr "מחבר אורח משוייך לא קיים"
488
+
489
+ #: php/class-coauthors-guest-authors.php:1217
490
+ msgid "No user exists with that ID"
491
+ msgstr "לא קיים משתמש עם ID זה"
492
+
493
+ #: php/class-coauthors-guest-authors.php:1275
494
+ msgid "Edit Profile"
495
+ msgstr "עריכת פרופיל"
496
+
497
+ #: php/class-coauthors-guest-authors.php:1284
498
+ msgid "Create Profile"
499
+ msgstr "יצירת פרופיל"
500
+
501
+ #: php/class-coauthors-wp-list-table.php:19
502
+ msgid "Co-Authors"
503
+ msgstr "מחברים שותפים"
504
+
505
+ #: php/class-coauthors-wp-list-table.php:20
506
+ msgid "Co-Author"
507
+ msgstr "מחבר שותף"
508
+
509
+ #: php/class-coauthors-wp-list-table.php:81
510
+ msgid "Show all"
511
+ msgstr "הצג הכל"
512
+
513
+ #: php/class-coauthors-wp-list-table.php:82
514
+ msgid "With linked account"
515
+ msgstr "עם חשבונות מקושרים"
516
+
517
+ #: php/class-coauthors-wp-list-table.php:83
518
+ msgid "Without linked account"
519
+ msgstr "ללא חשבונות מקושרים"
520
+
521
+ #: php/class-coauthors-wp-list-table.php:135
522
+ msgid "No matching guest authors were found."
523
+ msgstr "לא נמצאו מחברים-אורחים מתאימים."
524
+
525
+ #: php/class-coauthors-wp-list-table.php:215
526
+ msgid "Delete"
527
+ msgstr "מחיקה"
528
+
529
+ #: php/class-coauthors-wp-list-table.php:217
530
+ msgid "View Posts"
531
+ msgstr "הצגת פוסטים"
532
+
533
+ #: php/class-coauthors-wp-list-table.php:267
534
+ msgid "Filter"
535
+ msgstr "סינון"
536
+
537
+ #: php/class-wp-cli.php:220
538
+ msgid "Please specify a valid user_login"
539
+ msgstr "שם משתמש לא תקין"
540
+
541
+ #: php/class-wp-cli.php:223
542
+ msgid "Please specify a valid co-author login"
543
+ msgstr "מחבר אורח לא תקין"
544
+
545
+ #: php/class-wp-cli.php:230
546
+ msgid "Skipping - Post #%d already has co-authors assigned: %s"
547
+ msgstr "מדלג - לפוסט מספר #%d כבר משוייך מחבר אורח: %s"
548
+
549
+ #: php/class-wp-cli.php:235
550
+ msgid "Updating - Adding %s's byline to post #%d"
551
+ msgstr "מעדכן - מוסיף את %s לפוסט מספר #%d"
552
+
553
+ #: php/class-wp-cli.php:240
554
+ msgid "All done! %d posts were affected."
555
+ msgstr "בוצע! %d פוסטים הושפעו."
556
+
557
+ #: template-tags.php:79
558
+ msgid ""
559
+ "No post ID provided for CoAuthorsIterator constructor. Are you not in a loop "
560
+ "or is $post not set?"
561
+ msgstr ""
562
+
563
+ #: template-tags.php:133
564
+ msgid " and "
565
+ msgstr " ו"
566
+
567
+ #: template-tags.php:233 template-tags.php:468
568
+ msgid "Posts by %s"
569
+ msgstr "כתבות מאת %s"
570
+
571
+ #: template-tags.php:350
572
+ msgid "Visit %s&#8217;s website"
573
+ msgstr "מעבר לאתר של %s"
574
+
575
+ #. Plugin Name of the plugin/theme
576
+ msgid "Co-Authors Plus"
577
+ msgstr "מחברים שותפים פלוס"
578
+
579
+ #. Plugin URI of the plugin/theme
580
+ msgid "http://wordpress.org/extend/plugins/co-authors-plus/"
581
+ msgstr ""
582
+
583
+ #. Description of the plugin/theme
584
+ msgid ""
585
+ "Allows multiple authors to be assigned to a post. This plugin is an extended "
586
+ "version of the Co-Authors plugin developed by Weston Ruter."
587
+ msgstr ""
588
+ "מאפשר שיוך מספר מחברים לכל פוסט. התוסף הוא שדרוג של התוסף הישן Co-Authors "
589
+ "מאתר Weston Ruter."
590
+
591
+ #. Author of the plugin/theme
592
+ msgid "Mohammad Jangda, Daniel Bachhuber, Automattic"
593
+ msgstr ""
php/class-coauthors-guest-authors.php CHANGED
@@ -6,11 +6,11 @@
6
  * to give them access to the dashboard through a WP_User account
7
  */
8
 
9
- class CoAuthors_Guest_Authors
10
- {
11
 
12
- var $post_type = 'guest-author';
13
- var $parent_page = 'users.php';
 
14
  var $list_guest_authors_cap = 'list_users';
15
 
16
  public static $cache_group = 'coauthors-plus-guest-authors';
@@ -25,7 +25,7 @@ class CoAuthors_Guest_Authors
25
  add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
26
 
27
  // WP List Table for breaking out our Guest Authors
28
- require_once( dirname( __FILE__ ) . '/class-coauthors-wp-list-table.php' );
29
 
30
  // Get a co-author based on a query
31
  add_action( 'wp_ajax_search_coauthors_to_assign', array( $this, 'handle_ajax_search_coauthors_to_assign' ) );
@@ -67,7 +67,7 @@ class CoAuthors_Guest_Authors
67
  add_filter( 'user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 );
68
 
69
  // Add support for featured thumbnails that we can use for guest author avatars
70
- add_filter( 'get_avatar', array( $this, 'filter_get_avatar' ),10 ,5 );
71
 
72
  // Add a Personal Data Exporter to guest authors
73
  add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'filter_personal_data_exporter' ), 1 );
@@ -79,58 +79,61 @@ class CoAuthors_Guest_Authors
79
  $this->list_guest_authors_cap = apply_filters( 'coauthors_guest_author_manage_cap', $this->list_guest_authors_cap );
80
 
81
  // Set up default labels, but allow themes to modify
82
- $this->labels = apply_filters( 'coauthors_guest_author_labels', array(
83
- 'singular' => __( 'Guest Author', 'co-authors-plus' ),
84
- 'plural' => __( 'Guest Authors', 'co-authors-plus' ),
85
- 'all_items' => __( 'All Guest Authors', 'co-authors-plus' ),
86
- 'add_new_item' => __( 'Add New Guest Author', 'co-authors-plus' ),
87
- 'edit_item' => __( 'Edit Guest Author', 'co-authors-plus' ),
88
- 'new_item' => __( 'New Guest Author', 'co-authors-plus' ),
89
- 'view_item' => __( 'View Guest Author', 'co-authors-plus' ),
90
- 'search_items' => __( 'Search Guest Authors', 'co-authors-plus' ),
91
- 'not_found' => __( 'No guest authors found', 'co-authors-plus' ),
92
- 'not_found_in_trash' => __( 'No guest authors found in Trash', 'co-authors-plus' ),
93
- 'update_item' => __( 'Update Guest Author', 'co-authors-plus' ),
94
- 'metabox_about' => __( 'About the guest author', 'co-authors-plus' ),
95
- 'featured_image' => __( 'Avatar', 'co-authors-plus' ),
96
- 'set_featured_image' => __( 'Set Avatar', 'co-authors-plus' ),
97
- 'use_featured_image' => __( 'Use Avatar', 'co-authors-plus' ),
98
- 'remove_featured_image' => __( 'Remove Avatar', 'co-authors-plus' ),
99
- ) );
 
 
 
100
 
101
  // Register a post type to store our guest authors
102
  $args = array(
103
- 'label' => $this->labels['singular'],
104
- 'labels' => array(
105
- 'name' => isset( $this->labels['plural'] ) ? $this->labels['plural'] : '',
106
- 'singular_name' => isset( $this->labels['singular'] ) ? $this->labels['singular'] : '',
107
- 'add_new' => _x( 'Add New', 'guest author', 'co-authors-plus' ),
108
- 'all_items' => isset( $this->labels['all_items'] ) ? $this->labels['all_items'] : '',
109
- 'add_new_item' => isset( $this->labels['add_new_item'] ) ? $this->labels['add_new_item'] : '',
110
- 'edit_item' => isset( $this->labels['edit_item'] ) ? $this->labels['edit_item'] : '',
111
- 'new_item' => isset( $this->labels['new_item'] ) ? $this->labels['new_item'] : '',
112
- 'view_item' => isset( $this->labels['view_item'] ) ? $this->labels['view_item'] : '',
113
- 'search_items' => isset( $this->labels['search_items'] ) ? $this->labels['search_items'] : '',
114
- 'not_found' => isset( $this->labels['not_found'] ) ? $this->labels['not_found'] : '',
115
- 'not_found_in_trash' => isset( $this->labels['not_found_in_trash'] ) ? $this->labels['not_found_in_trash'] : '',
116
- 'featured_image' => isset( $this->labels['featured_image'] ) ? $this->labels['featured_image'] : '',
117
- 'set_featured_image' => isset( $this->labels['set_featured_image'] ) ? $this->labels['set_featured_image'] : '',
118
- 'use_featured_image' => isset( $this->labels['use_featured_image'] ) ? $this->labels['use_featured_image'] : '',
119
- 'remove_featured_image' => isset( $this->labels['remove_featured_image'] ) ? $this->labels['remove_featured_image'] : '',
120
- ),
121
- 'public' => true,
122
- 'publicly_queryable' => false,
123
- 'exclude_from_search' => true,
124
- 'show_in_menu' => false,
125
- 'supports' => array(
126
- 'thumbnail',
127
- ),
128
- 'taxonomies' => array(
129
- $coauthors_plus->coauthor_taxonomy,
130
- ),
131
- 'rewrite' => false,
132
- 'query_var' => false,
133
- );
134
  register_post_type( $this->post_type, $args );
135
 
136
  // Some of the common sizes used by get_avatar
@@ -154,23 +157,26 @@ class CoAuthors_Guest_Authors
154
  return $messages;
155
  }
156
 
157
- $guest_author = $this->get_guest_author_by( 'ID', $post->ID );
158
  $guest_author_link = $this->filter_author_link( '', $guest_author->ID, $guest_author->user_nicename );
159
 
160
  $messages[ $this->post_type ] = array(
161
- 0 => '', // Unused. Messages start at index 1.
162
- 1 => sprintf( __( 'Guest author updated. <a href="%s">View profile</a>', 'co-authors-plus' ), esc_url( $guest_author_link ) ),
163
- 2 => __( 'Custom field updated.', 'co-authors-plus' ),
164
- 3 => __( 'Custom field deleted.', 'co-authors-plus' ),
165
- 4 => __( 'Guest author updated.', 'co-authors-plus' ),
166
  /* translators: %s: date and time of the revision */
167
- 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Guest author restored to revision from %s', 'co-authors-plus' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
168
- 6 => sprintf( __( 'Guest author updated. <a href="%s">View profile</a>', 'co-authors-plus' ), esc_url( $guest_author_link ) ),
169
- 7 => __( 'Guest author saved.', 'co-authors-plus' ),
170
- 8 => sprintf( __( 'Guest author submitted. <a target="_blank" href="%s">Preview profile</a>', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ),
171
- 9 => sprintf( __( 'Guest author scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview profile</a>', 'co-authors-plus' ),
 
172
  // translators: Publish box date format, see http://php.net/date
173
- date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( $guest_author_link ) ),
 
 
174
  10 => sprintf( __( 'Guest author updated. <a target="_blank" href="%s">Preview profile</a>', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ),
175
  );
176
  return $messages;
@@ -207,7 +213,7 @@ class CoAuthors_Guest_Authors
207
  do_action( 'cap_guest_author_create' );
208
 
209
  // Redirect to the edit Guest Author screen
210
- $edit_link = get_edit_post_link( $post_id, 'redirect' );
211
  $redirect_to = add_query_arg( 'message', 'guest-author-created', $edit_link );
212
  wp_safe_redirect( esc_url_raw( $redirect_to ) );
213
  exit;
@@ -251,12 +257,14 @@ class CoAuthors_Guest_Authors
251
  break;
252
  // Reassign to a different user
253
  case 'reassign-another':
254
- $user_nicename = sanitize_title( $_POST['leave-assigned-to'] );
255
- $reassign_to = $coauthors_plus->get_coauthor_by( 'user_nicename', $user_nicename );
256
- if ( ! $reassign_to ) {
257
- wp_die( esc_html__( 'Co-author does not exists. Try again?', 'co-authors-plus' ) );
 
 
 
258
  }
259
- $reassign_to = $reassign_to->user_login;
260
  break;
261
  // Remove the byline, but don't delete the post
262
  case 'remove-byline':
@@ -270,8 +278,8 @@ class CoAuthors_Guest_Authors
270
  $retval = $this->delete( $guest_author->ID, $reassign_to );
271
 
272
  $args = array(
273
- 'page' => 'view-guest-authors',
274
- );
275
  if ( is_wp_error( $retval ) ) {
276
  $args['message'] = 'delete-error';
277
  } else {
@@ -298,6 +306,10 @@ class CoAuthors_Guest_Authors
298
  die();
299
  }
300
 
 
 
 
 
301
  $search = sanitize_text_field( $_GET['q'] );
302
  if ( ! empty( $_GET['guest_author'] ) ) {
303
  $ignore = array( $this->get_guest_author_by( 'ID', (int) $_GET['guest_author'] )->user_login );
@@ -306,14 +318,14 @@ class CoAuthors_Guest_Authors
306
  }
307
 
308
  $results = wp_list_pluck( $coauthors_plus->search_authors( $search, $ignore ), 'user_login' );
309
- $retval = array();
310
  foreach ( $results as $user_login ) {
311
  $coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $user_login );
312
  $retval[] = (object) array(
313
- 'display_name' => $coauthor->display_name,
314
- 'user_login' => $coauthor->user_login,
315
- 'id' => $coauthor->user_nicename,
316
- );
317
  }
318
  echo wp_json_encode( $retval );
319
  die();
@@ -380,7 +392,7 @@ class CoAuthors_Guest_Authors
380
 
381
  wp_enqueue_style( 'guest-authors-css', plugins_url( 'css/guest-authors.css', dirname( __FILE__ ) ), false, COAUTHORS_PLUS_VERSION );
382
  wp_enqueue_script( 'guest-authors-js', plugins_url( 'js/guest-authors.js', dirname( __FILE__ ) ), false, COAUTHORS_PLUS_VERSION );
383
- } else if ( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) && $this->post_type === get_post_type() ) {
384
  add_action( 'admin_head', array( $this, 'change_title_icon' ) );
385
  }
386
  }
@@ -475,19 +487,17 @@ class CoAuthors_Guest_Authors
475
  echo '<div class="wrap">';
476
  echo '<div class="icon32" id="icon-users"><br/></div>';
477
  echo '<h2>' . esc_html( sprintf( __( 'Delete %s', 'co-authors-plus ' ), $this->labels['plural'] ) ) . '</h2>';
478
- echo '<p>' . esc_html( sprintf( __( 'You have specified this %s for deletion:', 'co-authors-plus' ), strtolower( $this->labels['singular'] ) ) ) . '</p>';
479
  echo '<p>#' . esc_html( $guest_author->ID . ': ' . $guest_author->display_name ) . '</p>';
480
  // display wording differently per post count
481
  if ( 0 === $count ) {
482
  $post_count_message = '<p>' . sprintf( __( 'There are no posts associated with this guest author.', 'co-authors-plus' ), strtolower( $this->labels['singular'] ) ) . '</p>';
483
- }
484
- else {
485
- $note = '<p class="description">' . sprintf( __( "Note: If you'd like to delete the %s and all of their posts, you should delete their posts first and then come back to delete the %s.", 'co-authors-plus' ), strtolower( $this->labels['singular'] ), strtolower( $this->labels['singular'] ) ) . '</p>';
486
  if ( 1 === $count ) {
487
- $post_count_message = '<p>' . sprintf( __( 'There is %d post associated with this guest author. What should be done with the post assigned to this %s?', 'co-authors-plus' ), $count, strtolower( $this->labels['singular'] ) ) . '</p>';
488
- }
489
- else {
490
- $post_count_message = '<p>' . sprintf( __( 'There are %d posts associated with this guest author. What should be done with the posts assigned to this %s?', 'co-authors-plus' ), $count, strtolower( $this->labels['singular'] ) ) . '</p>';
491
  }
492
  $post_count_message .= $note;
493
  }
@@ -520,16 +530,14 @@ class CoAuthors_Guest_Authors
520
  echo '<li><label for="remove-byline">';
521
  echo '<input type="radio" id="remove-byline" class="reassign-option" name="reassign" value="remove-byline" />&nbsp;&nbsp;' . esc_html__( 'Remove byline from posts (but leave each post in its current status).', 'co-authors-plus' );
522
  echo '</label></li>';
523
- }
524
- else {
525
  echo '<input type="hidden" id="remove-byline" class="reassign-option" name="reassign" value="remove-byline" checked="checked" />';
526
  }
527
  echo '</ul></fieldset>';
528
  // disable disabled submit button for 0 post count
529
  if ( 0 === $count ) {
530
  submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary', 'submit', true );
531
- }
532
- else {
533
  submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary', 'submit', true, array( 'disabled' => 'disabled' ) );
534
  }
535
  echo '</form>';
@@ -581,14 +589,14 @@ class CoAuthors_Guest_Authors
581
  function metabox_manage_guest_author_slug() {
582
  global $post;
583
 
584
- $pm_key = $this->get_post_meta_key( 'user_login' );
585
  $existing_slug = get_post_meta( $post->ID, $pm_key, true );
586
 
587
  echo '<input type="text" disabled="disabled" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( urldecode( $existing_slug ) ) . '" />';
588
 
589
  // Taken from grist_authors.
590
  $linked_account_key = $this->get_post_meta_key( 'linked_account' );
591
- $linked_account = get_post_meta( $post->ID, $linked_account_key, true );
592
  if ( $user = get_user_by( 'login', $linked_account ) ) {
593
  $linked_account_id = $user->ID;
594
  } else {
@@ -606,15 +614,20 @@ class CoAuthors_Guest_Authors
606
  }
607
 
608
  echo '<p><label>' . esc_html__( 'WordPress User Mapping', 'co-authors-plus' ) . '</label> ';
609
- wp_dropdown_users( apply_filters( 'coauthors_guest_author_linked_account_args', array(
610
- 'show_option_none' => __( '-- Not mapped --', 'co-authors-plus' ),
611
- 'name' => esc_attr( $this->get_post_meta_key( 'linked_account' ) ),
612
- // If we're adding an author or if there is no post author (0), then use -1 (which is show_option_none).
613
- // We then take -1 on save and convert it back to 0. (#blamenacin)
614
- 'selected' => $linked_account_id,
615
- // Don't let user accounts to be linked to more than one guest author
616
- 'exclude' => $linked_account_user_ids,
617
- ) ) );
 
 
 
 
 
618
  echo '</p>';
619
 
620
  remove_filter( 'wp_dropdown_users', array( $this, 'filter_wp_dropdown_users_to_disable' ) );
@@ -642,7 +655,7 @@ class CoAuthors_Guest_Authors
642
  echo '<table class="form-table"><tbody>';
643
  foreach ( $fields as $field ) {
644
  $pm_key = $this->get_post_meta_key( $field['key'] );
645
- $value = get_post_meta( $post->ID, $pm_key, true );
646
  echo '<tr><th>';
647
  echo '<label for="' . esc_attr( $pm_key ) . '">' . esc_html( $field['label'] ) . '</label>';
648
  echo '</th><td>';
@@ -650,14 +663,14 @@ class CoAuthors_Guest_Authors
650
  if ( ! isset( $field['input'] ) ) {
651
  $field['input'] = 'text';
652
  }
653
- $field['input'] = apply_filters( 'coauthors_name_field_type_'. $pm_key , $field['input'] );
654
  switch ( $field['input'] ) {
655
  case 'checkbox':
656
- echo '<input type="checkbox" name="' . esc_attr( $pm_key ) . '"'. checked( '1', $value, false ) .' value="1"/>';
657
- break;
658
  default:
659
- echo '<input type="'. esc_attr( $field['input'] ) .'" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( $value ) . '" class="regular-text" />';
660
- break;
661
  }
662
  echo '</td></tr>';
663
  }
@@ -678,7 +691,7 @@ class CoAuthors_Guest_Authors
678
  echo '<table class="form-table"><tbody>';
679
  foreach ( $fields as $field ) {
680
  $pm_key = $this->get_post_meta_key( $field['key'] );
681
- $value = get_post_meta( $post->ID, $pm_key, true );
682
  echo '<tr><th>';
683
  echo '<label for="' . esc_attr( $pm_key ) . '">' . esc_html( $field['label'] ) . '</label>';
684
  echo '</th><td>';
@@ -686,14 +699,14 @@ class CoAuthors_Guest_Authors
686
  if ( ! isset( $field['input'] ) ) {
687
  $field['input'] = 'text';
688
  }
689
- $field['input'] = apply_filters( 'coauthors_name_field_type_'. $pm_key , $field['input'] );
690
  switch ( $field['input'] ) {
691
  case 'checkbox':
692
- echo '<input type="checkbox" name="' . esc_attr( $pm_key ) . '"'. checked( '1', $value, false ) .' value="1"/>';
693
- break;
694
  default:
695
- echo '<input type="'. esc_attr( $field['input'] ) .'" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( $value ) . '" class="regular-text" />';
696
- break;
697
  }
698
 
699
  echo '</td></tr>';
@@ -714,8 +727,9 @@ class CoAuthors_Guest_Authors
714
  echo '<table class="form-table"><tbody>';
715
  foreach ( $fields as $field ) {
716
  $pm_key = $this->get_post_meta_key( $field['key'] );
717
- $value = get_post_meta( $post->ID, $pm_key, true );
718
- printf( '
 
719
  <tr>
720
  <th>
721
  <label for="%s">%s</label>
@@ -771,7 +785,7 @@ class CoAuthors_Guest_Authors
771
 
772
  // Guest authors can't be created with the same user_login as a user
773
  $user_nicename = str_replace( 'cap-', '', $slug );
774
- $user = get_user_by( 'slug', $user_nicename );
775
  if ( $user
776
  && is_user_member_of_blog( $user->ID, get_current_blog_id() )
777
  && $user->user_login != get_post_meta( $original_args['ID'], $this->get_post_meta_key( 'linked_account' ), true ) ) {
@@ -812,7 +826,7 @@ class CoAuthors_Guest_Authors
812
  // 'user_login' should only be saved on post update if it doesn't exist
813
  if ( 'user_login' == $author_field['key'] && ! get_post_meta( $post_id, $key, true ) ) {
814
  $display_name_key = $this->get_post_meta_key( 'display_name' );
815
- $temp_slug = sanitize_title( $_POST[ $display_name_key ] );
816
  update_post_meta( $post_id, $key, $temp_slug );
817
  continue;
818
  }
@@ -849,7 +863,7 @@ class CoAuthors_Guest_Authors
849
  update_post_meta( $post_id, $key, $value );
850
  }
851
 
852
- $author = $this->get_guest_author_by( 'ID', $post_id );
853
  $author_term = $coauthors_plus->update_author_term( $author );
854
  // Add the author as a post term
855
  wp_set_post_terms( $post_id, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy, false );
@@ -865,8 +879,8 @@ class CoAuthors_Guest_Authors
865
  *
866
  * @since 3.0
867
  *
868
- * @param string $key Key to search by (login,email)
869
- * @param string $value Value to search for
870
  * @param object|false $coauthor The guest author on success, false on failure
871
  */
872
  function get_guest_author_by( $key, $value, $force = false ) {
@@ -886,17 +900,17 @@ class CoAuthors_Guest_Authors
886
  switch ( $key ) {
887
  case 'ID':
888
  case 'id':
889
- $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID=%d AND post_type = %s", $value, $this->post_type );
890
- $post_id = $wpdb->get_var( $query );
891
  if ( empty( $post_id ) ) {
892
  $post_id = '0';
893
  }
894
  break;
895
  case 'user_nicename':
896
  case 'post_name':
897
- $value = $this->get_post_meta_key( $value );
898
- $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name=%s AND post_type = %s", $value, $this->post_type );
899
- $post_id = $wpdb->get_var( $query );
900
  if ( empty( $post_id ) ) {
901
  $post_id = '0';
902
  }
@@ -912,8 +926,8 @@ class CoAuthors_Guest_Authors
912
  if ( 'user_login' == $key ) {
913
  $value = preg_replace( '#^cap\-#', '', $value );
914
  }
915
- $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value=%s;", $this->get_post_meta_key( $key ), $value );
916
- $post_id = $wpdb->get_var( $query );
917
  if ( empty( $post_id ) ) {
918
  if ( 'user_login' == $key ) {
919
  return $this->get_guest_author_by( 'post_name', $value ); // fallback to post_name in case the guest author isn't a linked account
@@ -939,8 +953,8 @@ class CoAuthors_Guest_Authors
939
  // Load the guest author fields
940
  $fields = $this->get_guest_author_fields();
941
  foreach ( $fields as $field ) {
942
- $key = $field['key'];
943
- $pm_key = $this->get_post_meta_key( $field['key'] );
944
  $guest_author[ $key ] = get_post_meta( $post_id, $pm_key, true );
945
  }
946
  // Support for non-Latin characters. They're stored as urlencoded slugs
@@ -948,7 +962,7 @@ class CoAuthors_Guest_Authors
948
 
949
  // Hack to model the WP_User object
950
  $guest_author['user_nicename'] = sanitize_title( $guest_author['user_login'] );
951
- $guest_author['type'] = 'guest-author';
952
 
953
  wp_cache_set( $cache_key, (object) $guest_author, self::$cache_group );
954
 
@@ -958,10 +972,10 @@ class CoAuthors_Guest_Authors
958
  /**
959
  * Get an thumbnail for a Guest Author object
960
  *
961
- * @param object The Guest Author object for which to retrieve the thumbnail.
962
- * @param int The desired image size.
963
- * @param array|string Optional. An array or string of additional classes. Default null.
964
- * @return string The thumbnail image tag, or null if one doesn't exist.
965
  */
966
  function get_guest_author_thumbnail( $guest_author, $size, $class = null ) {
967
  // See if the guest author has an avatar
@@ -993,78 +1007,78 @@ class CoAuthors_Guest_Authors
993
  */
994
  function get_guest_author_fields( $groups = 'all' ) {
995
 
996
- $groups = (array) $groups;
997
  $global_fields = array(
998
- // Hidden (included in object, no UI elements)
999
- array(
1000
- 'key' => 'ID',
1001
- 'label' => __( 'ID', 'co-authors-plus' ),
1002
- 'group' => 'hidden',
1003
- 'input' => 'hidden',
1004
- ),
1005
- // Name
1006
- array(
1007
- 'key' => 'display_name',
1008
- 'label' => __( 'Display Name', 'co-authors-plus' ),
1009
- 'group' => 'name',
1010
- 'required' => true,
1011
- ),
1012
- array(
1013
- 'key' => 'first_name',
1014
- 'label' => __( 'First Name', 'co-authors-plus' ),
1015
- 'group' => 'name',
1016
- ),
1017
- array(
1018
- 'key' => 'last_name',
1019
- 'label' => __( 'Last Name', 'co-authors-plus' ),
1020
- 'group' => 'name',
1021
- ),
1022
- array(
1023
- 'key' => 'user_login',
1024
- 'label' => __( 'Slug', 'co-authors-plus' ),
1025
- 'group' => 'slug',
1026
- 'required' => true,
1027
- ),
1028
- // Contact info
1029
- array(
1030
- 'key' => 'user_email',
1031
- 'label' => __( 'E-mail', 'co-authors-plus' ),
1032
- 'group' => 'contact-info',
1033
- 'input' => 'email',
1034
- ),
1035
- array(
1036
- 'key' => 'linked_account',
1037
- 'label' => __( 'Linked Account', 'co-authors-plus' ),
1038
- 'group' => 'slug',
1039
- ),
1040
- array(
1041
- 'key' => 'website',
1042
- 'label' => __( 'Website', 'co-authors-plus' ),
1043
- 'group' => 'contact-info',
1044
- 'input' => 'url',
1045
- ),
1046
- array(
1047
- 'key' => 'aim',
1048
- 'label' => __( 'AIM', 'co-authors-plus' ),
1049
- 'group' => 'contact-info',
1050
- ),
1051
- array(
1052
- 'key' => 'yahooim',
1053
- 'label' => __( 'Yahoo IM', 'co-authors-plus' ),
1054
- 'group' => 'contact-info',
1055
- ),
1056
- array(
1057
- 'key' => 'jabber',
1058
- 'label' => __( 'Jabber / Google Talk', 'co-authors-plus' ),
1059
- 'group' => 'contact-info',
1060
- ),
1061
- array(
1062
- 'key' => 'description',
1063
- 'label' => __( 'Biographical Info', 'co-authors-plus' ),
1064
- 'group' => 'about',
1065
- 'sanitize_function' => 'wp_filter_post_kses',
1066
- ),
1067
- );
1068
  $fields_to_return = array();
1069
  foreach ( $global_fields as $single_field ) {
1070
  if ( in_array( $single_field['group'], $groups ) || 'all' === $groups[0] && 'hidden' !== $single_field['group'] ) {
@@ -1131,20 +1145,20 @@ class CoAuthors_Guest_Authors
1131
  global $wpdb;
1132
 
1133
  $cache_key = 'all-linked-accounts';
1134
- $retval = wp_cache_get( $cache_key, self::$cache_group );
1135
 
1136
  if ( true === $force || false === $retval ) {
1137
  $user_logins = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value !=''", $this->get_post_meta_key( 'linked_account' ) ) );
1138
- $users = array();
1139
  foreach ( $user_logins as $user_login ) {
1140
  $user = get_user_by( 'login', $user_login );
1141
  if ( ! $user ) {
1142
  continue;
1143
  }
1144
  $users[] = array(
1145
- 'ID' => $user->ID,
1146
- 'user_login' => $user->user_login,
1147
- );
1148
  }
1149
  $retval = $users;
1150
  wp_cache_set( $cache_key, $retval, self::$cache_group );
@@ -1202,7 +1216,7 @@ class CoAuthors_Guest_Authors
1202
 
1203
  if ( 'post_name' == $key ) {
1204
  $value_key = 'user_nicename';
1205
- } else if ( 'login' == $key ) {
1206
  $value_key = 'user_login';
1207
  }
1208
 
@@ -1244,11 +1258,11 @@ class CoAuthors_Guest_Authors
1244
 
1245
  // Create the primary post object
1246
  $new_post = array(
1247
- 'post_title' => $args['display_name'],
1248
- 'post_name' => sanitize_title( $this->get_post_meta_key( $args['user_login'] ) ),
1249
- 'post_type' => $this->post_type,
1250
- );
1251
- $post_id = wp_insert_post( $new_post, true );
1252
  if ( is_wp_error( $post_id ) ) {
1253
  return $post_id;
1254
  }
@@ -1264,8 +1278,8 @@ class CoAuthors_Guest_Authors
1264
  }
1265
 
1266
  // Attach the avatar / featured image.
1267
- if ( ! empty( $args[ 'avatar' ] ) ) {
1268
- set_post_thumbnail( $post_id, $args[ 'avatar' ] );
1269
  }
1270
 
1271
  // Make sure the author term exists and that we're assigning it to this post type
@@ -1284,7 +1298,7 @@ class CoAuthors_Guest_Authors
1284
  *
1285
  * @since 3.0
1286
  *
1287
- * @param int $post_id The ID for the guest author profile
1288
  * @param string $reassign_to User login value for the co-author to reassign posts to
1289
  * @return bool|WP_Error $success True on success, WP_Error on a failure
1290
  */
@@ -1314,7 +1328,14 @@ class CoAuthors_Guest_Authors
1314
  $reassign_to_term = $coauthors_plus->get_author_term( $reassign_to_author );
1315
  // In the case where the guest author and its linked account shared the same term, we don't want to reassign
1316
  if ( $guest_author_term->term_id != $reassign_to_term->term_id ) {
1317
- wp_delete_term( $guest_author_term->term_id, $coauthors_plus->coauthor_taxonomy, array( 'default' => $reassign_to_term->term_id, 'force_default' => true ) );
 
 
 
 
 
 
 
1318
  }
1319
  } else {
1320
  wp_delete_term( $guest_author_term->term_id, $coauthors_plus->coauthor_taxonomy );
@@ -1359,7 +1380,7 @@ class CoAuthors_Guest_Authors
1359
  $guest_author['linked_account'] = $guest_author['user_login'];
1360
  if ( ! empty( $guest_author['display_name'] ) && $guest_author['display_name'] != $guest_author['user_login'] ) {
1361
  $guest_author['user_login'] = sanitize_title( $guest_author['display_name'] );
1362
- } else if ( ! empty( $guest_author['first_name'] ) && ! empty( $guest_author['last_name'] ) ) {
1363
  $guest_author['user_login'] = sanitize_title( $guest_author['first_name'] . ' ' . $guest_author['last_name'] );
1364
  }
1365
 
@@ -1391,7 +1412,7 @@ class CoAuthors_Guest_Authors
1391
  *
1392
  * @since 3.0
1393
  *
1394
- * @param array $actions The existing actions to perform on a user
1395
  * @param object $user_object A WP_User object
1396
  * @return array $actions Modified actions
1397
  */
@@ -1403,14 +1424,14 @@ class CoAuthors_Guest_Authors
1403
 
1404
  $new_actions = array();
1405
  if ( $guest_author = $this->get_guest_author_by( 'linked_account', $user_object->user_login ) ) {
1406
- $edit_guest_author_link = get_edit_post_link( $guest_author->ID );
1407
  $new_actions['edit-guest-author'] = '<a href="' . esc_url( $edit_guest_author_link ) . '">' . __( 'Edit Profile', 'co-authors-plus' ) . '</a>';
1408
  } else {
1409
- $query_args = array(
1410
- 'action' => 'cap-create-guest-author',
1411
- 'user_id' => $user_object->ID,
1412
- 'nonce' => wp_create_nonce( 'create-guest-author' ),
1413
- );
1414
  $create_guest_author_link = add_query_arg( array_map( 'rawurlencode', $query_args ), admin_url( $this->parent_page ) );
1415
  if ( apply_filters( 'coauthors_show_create_profile_user_link', false ) ) {
1416
  $new_actions['create-guest-author'] = '<a href="' . esc_url( $create_guest_author_link ) . '">' . __( 'Create Profile', 'co-authors-plus' ) . '</a>';
@@ -1506,9 +1527,9 @@ class CoAuthors_Guest_Authors
1506
  if ( '' == $permalink_structure ) {
1507
  $link = home_url( "?feed=$feed&amp;author=" . $author->ID );
1508
  } else {
1509
- $link = get_author_posts_url( $author->ID );
1510
  $feed_link = ( get_default_feed() === $feed ) ? 'feed' : "feed/$feed";
1511
- $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' );
1512
  }
1513
 
1514
  return $link;
@@ -1534,7 +1555,7 @@ class CoAuthors_Guest_Authors
1534
  * @since 3.3.1
1535
  *
1536
  * @param string $email_address The guest author email address.
1537
- * @return array An array of personal data.
1538
  */
1539
  public function personal_data_exporter( $email_address ) {
1540
  $email_address = trim( $email_address );
@@ -1551,17 +1572,17 @@ class CoAuthors_Guest_Authors
1551
  }
1552
 
1553
  $author_data = array(
1554
- 'ID' => __( 'ID', 'co-authors-plus' ),
1555
- 'user_login' => __( 'Login Name', 'co-authors-plus' ),
1556
- 'display_name' => __( 'Display Name', 'co-authors-plus' ),
1557
- 'user_email' => __( 'Email', 'co-authors-plus' ),
1558
- 'first_name' => __( 'First Name', 'co-authors-plus' ),
1559
- 'last_name' => __( 'Last Name', 'co-authors-plus' ),
1560
- 'website' => __( 'Website', 'co-authors-plus' ),
1561
- 'aim' => __( 'AIM', 'co-authors-plus' ),
1562
- 'yahooim' => __( 'Yahoo IM', 'co-authors-plus' ),
1563
- 'jabber' => __( 'Jabber / Google Talk', 'co-authors-plus' ),
1564
- 'description' => __( 'Biographical Info', 'co-authors-plus' ),
1565
  );
1566
 
1567
  $author_data_to_export = array();
@@ -1586,7 +1607,7 @@ class CoAuthors_Guest_Authors
1586
  * @param int $author->ID The guest author ID
1587
  * @param string $email_address The guest author email address
1588
  */
1589
- $extra_data = apply_filters( 'coauthors_guest_author_personal_export_extra_data', [], $author->ID, $email_address );
1590
 
1591
  if ( is_array( $extra_data ) && ! empty( $extra_data ) ) {
1592
  $author_data_to_export = array_merge( $author_data_to_export, $extra_data );
6
  * to give them access to the dashboard through a WP_User account
7
  */
8
 
9
+ class CoAuthors_Guest_Authors {
 
10
 
11
+
12
+ var $post_type = 'guest-author';
13
+ var $parent_page = 'users.php';
14
  var $list_guest_authors_cap = 'list_users';
15
 
16
  public static $cache_group = 'coauthors-plus-guest-authors';
25
  add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
26
 
27
  // WP List Table for breaking out our Guest Authors
28
+ require_once dirname( __FILE__ ) . '/class-coauthors-wp-list-table.php';
29
 
30
  // Get a co-author based on a query
31
  add_action( 'wp_ajax_search_coauthors_to_assign', array( $this, 'handle_ajax_search_coauthors_to_assign' ) );
67
  add_filter( 'user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 );
68
 
69
  // Add support for featured thumbnails that we can use for guest author avatars
70
+ add_filter( 'get_avatar', array( $this, 'filter_get_avatar' ), 10, 5 );
71
 
72
  // Add a Personal Data Exporter to guest authors
73
  add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'filter_personal_data_exporter' ), 1 );
79
  $this->list_guest_authors_cap = apply_filters( 'coauthors_guest_author_manage_cap', $this->list_guest_authors_cap );
80
 
81
  // Set up default labels, but allow themes to modify
82
+ $this->labels = apply_filters(
83
+ 'coauthors_guest_author_labels',
84
+ array(
85
+ 'singular' => __( 'Guest Author', 'co-authors-plus' ),
86
+ 'plural' => __( 'Guest Authors', 'co-authors-plus' ),
87
+ 'all_items' => __( 'All Guest Authors', 'co-authors-plus' ),
88
+ 'add_new_item' => __( 'Add New Guest Author', 'co-authors-plus' ),
89
+ 'edit_item' => __( 'Edit Guest Author', 'co-authors-plus' ),
90
+ 'new_item' => __( 'New Guest Author', 'co-authors-plus' ),
91
+ 'view_item' => __( 'View Guest Author', 'co-authors-plus' ),
92
+ 'search_items' => __( 'Search Guest Authors', 'co-authors-plus' ),
93
+ 'not_found' => __( 'No guest authors found', 'co-authors-plus' ),
94
+ 'not_found_in_trash' => __( 'No guest authors found in Trash', 'co-authors-plus' ),
95
+ 'update_item' => __( 'Update Guest Author', 'co-authors-plus' ),
96
+ 'metabox_about' => __( 'About the guest author', 'co-authors-plus' ),
97
+ 'featured_image' => __( 'Avatar', 'co-authors-plus' ),
98
+ 'set_featured_image' => __( 'Set Avatar', 'co-authors-plus' ),
99
+ 'use_featured_image' => __( 'Use Avatar', 'co-authors-plus' ),
100
+ 'remove_featured_image' => __( 'Remove Avatar', 'co-authors-plus' ),
101
+ )
102
+ );
103
 
104
  // Register a post type to store our guest authors
105
  $args = array(
106
+ 'label' => $this->labels['singular'],
107
+ 'labels' => array(
108
+ 'name' => isset( $this->labels['plural'] ) ? $this->labels['plural'] : '',
109
+ 'singular_name' => isset( $this->labels['singular'] ) ? $this->labels['singular'] : '',
110
+ 'add_new' => _x( 'Add New', 'guest author', 'co-authors-plus' ),
111
+ 'all_items' => isset( $this->labels['all_items'] ) ? $this->labels['all_items'] : '',
112
+ 'add_new_item' => isset( $this->labels['add_new_item'] ) ? $this->labels['add_new_item'] : '',
113
+ 'edit_item' => isset( $this->labels['edit_item'] ) ? $this->labels['edit_item'] : '',
114
+ 'new_item' => isset( $this->labels['new_item'] ) ? $this->labels['new_item'] : '',
115
+ 'view_item' => isset( $this->labels['view_item'] ) ? $this->labels['view_item'] : '',
116
+ 'search_items' => isset( $this->labels['search_items'] ) ? $this->labels['search_items'] : '',
117
+ 'not_found' => isset( $this->labels['not_found'] ) ? $this->labels['not_found'] : '',
118
+ 'not_found_in_trash' => isset( $this->labels['not_found_in_trash'] ) ? $this->labels['not_found_in_trash'] : '',
119
+ 'featured_image' => isset( $this->labels['featured_image'] ) ? $this->labels['featured_image'] : '',
120
+ 'set_featured_image' => isset( $this->labels['set_featured_image'] ) ? $this->labels['set_featured_image'] : '',
121
+ 'use_featured_image' => isset( $this->labels['use_featured_image'] ) ? $this->labels['use_featured_image'] : '',
122
+ 'remove_featured_image' => isset( $this->labels['remove_featured_image'] ) ? $this->labels['remove_featured_image'] : '',
123
+ ),
124
+ 'public' => true,
125
+ 'publicly_queryable' => false,
126
+ 'exclude_from_search' => true,
127
+ 'show_in_menu' => false,
128
+ 'supports' => array(
129
+ 'thumbnail',
130
+ ),
131
+ 'taxonomies' => array(
132
+ $coauthors_plus->coauthor_taxonomy,
133
+ ),
134
+ 'rewrite' => false,
135
+ 'query_var' => false,
136
+ );
137
  register_post_type( $this->post_type, $args );
138
 
139
  // Some of the common sizes used by get_avatar
157
  return $messages;
158
  }
159
 
160
+ $guest_author = $this->get_guest_author_by( 'ID', $post->ID );
161
  $guest_author_link = $this->filter_author_link( '', $guest_author->ID, $guest_author->user_nicename );
162
 
163
  $messages[ $this->post_type ] = array(
164
+ 0 => '', // Unused. Messages start at index 1.
165
+ 1 => sprintf( __( 'Guest author updated. <a href="%s">View profile</a>', 'co-authors-plus' ), esc_url( $guest_author_link ) ),
166
+ 2 => __( 'Custom field updated.', 'co-authors-plus' ),
167
+ 3 => __( 'Custom field deleted.', 'co-authors-plus' ),
168
+ 4 => __( 'Guest author updated.', 'co-authors-plus' ),
169
  /* translators: %s: date and time of the revision */
170
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Guest author restored to revision from %s', 'co-authors-plus' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
171
+ 6 => sprintf( __( 'Guest author updated. <a href="%s">View profile</a>', 'co-authors-plus' ), esc_url( $guest_author_link ) ),
172
+ 7 => __( 'Guest author saved.', 'co-authors-plus' ),
173
+ 8 => sprintf( __( 'Guest author submitted. <a target="_blank" href="%s">Preview profile</a>', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ),
174
+ 9 => sprintf(
175
+ __( 'Guest author scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview profile</a>', 'co-authors-plus' ),
176
  // translators: Publish box date format, see http://php.net/date
177
+ date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ),
178
+ esc_url( $guest_author_link )
179
+ ),
180
  10 => sprintf( __( 'Guest author updated. <a target="_blank" href="%s">Preview profile</a>', 'co-authors-plus' ), esc_url( add_query_arg( 'preview', 'true', $guest_author_link ) ) ),
181
  );
182
  return $messages;
213
  do_action( 'cap_guest_author_create' );
214
 
215
  // Redirect to the edit Guest Author screen
216
+ $edit_link = get_edit_post_link( $post_id, 'redirect' );
217
  $redirect_to = add_query_arg( 'message', 'guest-author-created', $edit_link );
218
  wp_safe_redirect( esc_url_raw( $redirect_to ) );
219
  exit;
257
  break;
258
  // Reassign to a different user
259
  case 'reassign-another':
260
+ if ( isset( $_POST['leave-assigned-to'] ) ) {
261
+ $user_nicename = sanitize_title( $_POST['leave-assigned-to'] );
262
+ $reassign_to = $coauthors_plus->get_coauthor_by( 'user_nicename', $user_nicename );
263
+ if ( ! $reassign_to ) {
264
+ wp_die( esc_html__( 'Co-author does not exists. Try again?', 'co-authors-plus' ) );
265
+ }
266
+ $reassign_to = $reassign_to->user_login;
267
  }
 
268
  break;
269
  // Remove the byline, but don't delete the post
270
  case 'remove-byline':
278
  $retval = $this->delete( $guest_author->ID, $reassign_to );
279
 
280
  $args = array(
281
+ 'page' => 'view-guest-authors',
282
+ );
283
  if ( is_wp_error( $retval ) ) {
284
  $args['message'] = 'delete-error';
285
  } else {
306
  die();
307
  }
308
 
309
+ if ( ! isset( $_GET['q'] ) ) {
310
+ die();
311
+ }
312
+
313
  $search = sanitize_text_field( $_GET['q'] );
314
  if ( ! empty( $_GET['guest_author'] ) ) {
315
  $ignore = array( $this->get_guest_author_by( 'ID', (int) $_GET['guest_author'] )->user_login );
318
  }
319
 
320
  $results = wp_list_pluck( $coauthors_plus->search_authors( $search, $ignore ), 'user_login' );
321
+ $retval = array();
322
  foreach ( $results as $user_login ) {
323
  $coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $user_login );
324
  $retval[] = (object) array(
325
+ 'display_name' => $coauthor->display_name,
326
+ 'user_login' => $coauthor->user_login,
327
+ 'id' => $coauthor->user_nicename,
328
+ );
329
  }
330
  echo wp_json_encode( $retval );
331
  die();
392
 
393
  wp_enqueue_style( 'guest-authors-css', plugins_url( 'css/guest-authors.css', dirname( __FILE__ ) ), false, COAUTHORS_PLUS_VERSION );
394
  wp_enqueue_script( 'guest-authors-js', plugins_url( 'js/guest-authors.js', dirname( __FILE__ ) ), false, COAUTHORS_PLUS_VERSION );
395
+ } elseif ( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) && $this->post_type === get_post_type() ) {
396
  add_action( 'admin_head', array( $this, 'change_title_icon' ) );
397
  }
398
  }
487
  echo '<div class="wrap">';
488
  echo '<div class="icon32" id="icon-users"><br/></div>';
489
  echo '<h2>' . esc_html( sprintf( __( 'Delete %s', 'co-authors-plus ' ), $this->labels['plural'] ) ) . '</h2>';
490
+ echo '<p>' . esc_html( sprintf( __( 'You have specified this %s for deletion:', 'co-authors-plus' ), strtolower( $this->labels['singular'] ) ) ) . '</p>';
491
  echo '<p>#' . esc_html( $guest_author->ID . ': ' . $guest_author->display_name ) . '</p>';
492
  // display wording differently per post count
493
  if ( 0 === $count ) {
494
  $post_count_message = '<p>' . sprintf( __( 'There are no posts associated with this guest author.', 'co-authors-plus' ), strtolower( $this->labels['singular'] ) ) . '</p>';
495
+ } else {
496
+ $note = '<p class="description">' . sprintf( __( "Note: If you'd like to delete the %1\$s and all of their posts, you should delete their posts first and then come back to delete the %2\$s.", 'co-authors-plus' ), strtolower( $this->labels['singular'] ), strtolower( $this->labels['singular'] ) ) . '</p>';
 
497
  if ( 1 === $count ) {
498
+ $post_count_message = '<p>' . sprintf( __( 'There is %1$d post associated with this guest author. What should be done with the post assigned to this %2$s?', 'co-authors-plus' ), $count, strtolower( $this->labels['singular'] ) ) . '</p>';
499
+ } else {
500
+ $post_count_message = '<p>' . sprintf( __( 'There are %1$d posts associated with this guest author. What should be done with the posts assigned to this %2$s?', 'co-authors-plus' ), $count, strtolower( $this->labels['singular'] ) ) . '</p>';
 
501
  }
502
  $post_count_message .= $note;
503
  }
530
  echo '<li><label for="remove-byline">';
531
  echo '<input type="radio" id="remove-byline" class="reassign-option" name="reassign" value="remove-byline" />&nbsp;&nbsp;' . esc_html__( 'Remove byline from posts (but leave each post in its current status).', 'co-authors-plus' );
532
  echo '</label></li>';
533
+ } else {
 
534
  echo '<input type="hidden" id="remove-byline" class="reassign-option" name="reassign" value="remove-byline" checked="checked" />';
535
  }
536
  echo '</ul></fieldset>';
537
  // disable disabled submit button for 0 post count
538
  if ( 0 === $count ) {
539
  submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary', 'submit', true );
540
+ } else {
 
541
  submit_button( __( 'Confirm Deletion', 'co-authors-plus' ), 'secondary', 'submit', true, array( 'disabled' => 'disabled' ) );
542
  }
543
  echo '</form>';
589
  function metabox_manage_guest_author_slug() {
590
  global $post;
591
 
592
+ $pm_key = $this->get_post_meta_key( 'user_login' );
593
  $existing_slug = get_post_meta( $post->ID, $pm_key, true );
594
 
595
  echo '<input type="text" disabled="disabled" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( urldecode( $existing_slug ) ) . '" />';
596
 
597
  // Taken from grist_authors.
598
  $linked_account_key = $this->get_post_meta_key( 'linked_account' );
599
+ $linked_account = get_post_meta( $post->ID, $linked_account_key, true );
600
  if ( $user = get_user_by( 'login', $linked_account ) ) {
601
  $linked_account_id = $user->ID;
602
  } else {
614
  }
615
 
616
  echo '<p><label>' . esc_html__( 'WordPress User Mapping', 'co-authors-plus' ) . '</label> ';
617
+ wp_dropdown_users(
618
+ apply_filters(
619
+ 'coauthors_guest_author_linked_account_args',
620
+ array(
621
+ 'show_option_none' => __( '-- Not mapped --', 'co-authors-plus' ),
622
+ 'name' => esc_attr( $this->get_post_meta_key( 'linked_account' ) ),
623
+ // If we're adding an author or if there is no post author (0), then use -1 (which is show_option_none).
624
+ // We then take -1 on save and convert it back to 0. (#blamenacin)
625
+ 'selected' => $linked_account_id,
626
+ // Don't let user accounts to be linked to more than one guest author
627
+ 'exclude' => $linked_account_user_ids,
628
+ )
629
+ )
630
+ );
631
  echo '</p>';
632
 
633
  remove_filter( 'wp_dropdown_users', array( $this, 'filter_wp_dropdown_users_to_disable' ) );
655
  echo '<table class="form-table"><tbody>';
656
  foreach ( $fields as $field ) {
657
  $pm_key = $this->get_post_meta_key( $field['key'] );
658
+ $value = get_post_meta( $post->ID, $pm_key, true );
659
  echo '<tr><th>';
660
  echo '<label for="' . esc_attr( $pm_key ) . '">' . esc_html( $field['label'] ) . '</label>';
661
  echo '</th><td>';
663
  if ( ! isset( $field['input'] ) ) {
664
  $field['input'] = 'text';
665
  }
666
+ $field['input'] = apply_filters( 'coauthors_name_field_type_' . $pm_key, $field['input'] );
667
  switch ( $field['input'] ) {
668
  case 'checkbox':
669
+ echo '<input type="checkbox" name="' . esc_attr( $pm_key ) . '"' . checked( '1', $value, false ) . ' value="1"/>';
670
+ break;
671
  default:
672
+ echo '<input type="' . esc_attr( $field['input'] ) . '" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( $value ) . '" class="regular-text" />';
673
+ break;
674
  }
675
  echo '</td></tr>';
676
  }
691
  echo '<table class="form-table"><tbody>';
692
  foreach ( $fields as $field ) {
693
  $pm_key = $this->get_post_meta_key( $field['key'] );
694
+ $value = get_post_meta( $post->ID, $pm_key, true );
695
  echo '<tr><th>';
696
  echo '<label for="' . esc_attr( $pm_key ) . '">' . esc_html( $field['label'] ) . '</label>';
697
  echo '</th><td>';
699
  if ( ! isset( $field['input'] ) ) {
700
  $field['input'] = 'text';
701
  }
702
+ $field['input'] = apply_filters( 'coauthors_name_field_type_' . $pm_key, $field['input'] );
703
  switch ( $field['input'] ) {
704
  case 'checkbox':
705
+ echo '<input type="checkbox" name="' . esc_attr( $pm_key ) . '"' . checked( '1', $value, false ) . ' value="1"/>';
706
+ break;
707
  default:
708
+ echo '<input type="' . esc_attr( $field['input'] ) . '" name="' . esc_attr( $pm_key ) . '" value="' . esc_attr( $value ) . '" class="regular-text" />';
709
+ break;
710
  }
711
 
712
  echo '</td></tr>';
727
  echo '<table class="form-table"><tbody>';
728
  foreach ( $fields as $field ) {
729
  $pm_key = $this->get_post_meta_key( $field['key'] );
730
+ $value = get_post_meta( $post->ID, $pm_key, true );
731
+ printf(
732
+ '
733
  <tr>
734
  <th>
735
  <label for="%s">%s</label>
785
 
786
  // Guest authors can't be created with the same user_login as a user
787
  $user_nicename = str_replace( 'cap-', '', $slug );
788
+ $user = get_user_by( 'slug', $user_nicename );
789
  if ( $user
790
  && is_user_member_of_blog( $user->ID, get_current_blog_id() )
791
  && $user->user_login != get_post_meta( $original_args['ID'], $this->get_post_meta_key( 'linked_account' ), true ) ) {
826
  // 'user_login' should only be saved on post update if it doesn't exist
827
  if ( 'user_login' == $author_field['key'] && ! get_post_meta( $post_id, $key, true ) ) {
828
  $display_name_key = $this->get_post_meta_key( 'display_name' );
829
+ $temp_slug = sanitize_title( $_POST[ $display_name_key ] ); // phpcs:ignore
830
  update_post_meta( $post_id, $key, $temp_slug );
831
  continue;
832
  }
863
  update_post_meta( $post_id, $key, $value );
864
  }
865
 
866
+ $author = $this->get_guest_author_by( 'ID', $post_id );
867
  $author_term = $coauthors_plus->update_author_term( $author );
868
  // Add the author as a post term
869
  wp_set_post_terms( $post_id, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy, false );
879
  *
880
  * @since 3.0
881
  *
882
+ * @param string $key Key to search by (login,email)
883
+ * @param string $value Value to search for
884
  * @param object|false $coauthor The guest author on success, false on failure
885
  */
886
  function get_guest_author_by( $key, $value, $force = false ) {
900
  switch ( $key ) {
901
  case 'ID':
902
  case 'id':
903
+ $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID=%d AND post_type = %s", $value, $this->post_type );
904
+ $post_id = $wpdb->get_var( $query ); // phpcs:ignore
905
  if ( empty( $post_id ) ) {
906
  $post_id = '0';
907
  }
908
  break;
909
  case 'user_nicename':
910
  case 'post_name':
911
+ $value = $this->get_post_meta_key( $value );
912
+ $query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name=%s AND post_type = %s", $value, $this->post_type );
913
+ $post_id = $wpdb->get_var( $query ); // phpcs:ignore
914
  if ( empty( $post_id ) ) {
915
  $post_id = '0';
916
  }
926
  if ( 'user_login' == $key ) {
927
  $value = preg_replace( '#^cap\-#', '', $value );
928
  }
929
+ $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value=%s;", $this->get_post_meta_key( $key ), $value );
930
+ $post_id = $wpdb->get_var( $query ); // phpcs:ignore
931
  if ( empty( $post_id ) ) {
932
  if ( 'user_login' == $key ) {
933
  return $this->get_guest_author_by( 'post_name', $value ); // fallback to post_name in case the guest author isn't a linked account
953
  // Load the guest author fields
954
  $fields = $this->get_guest_author_fields();
955
  foreach ( $fields as $field ) {
956
+ $key = $field['key'];
957
+ $pm_key = $this->get_post_meta_key( $field['key'] );
958
  $guest_author[ $key ] = get_post_meta( $post_id, $pm_key, true );
959
  }
960
  // Support for non-Latin characters. They're stored as urlencoded slugs
962
 
963
  // Hack to model the WP_User object
964
  $guest_author['user_nicename'] = sanitize_title( $guest_author['user_login'] );
965
+ $guest_author['type'] = 'guest-author';
966
 
967
  wp_cache_set( $cache_key, (object) $guest_author, self::$cache_group );
968
 
972
  /**
973
  * Get an thumbnail for a Guest Author object
974
  *
975
+ * @param object The Guest Author object for which to retrieve the thumbnail.
976
+ * @param int The desired image size.
977
+ * @param array|string Optional. An array or string of additional classes. Default null.
978
+ * @return string The thumbnail image tag, or null if one doesn't exist.
979
  */
980
  function get_guest_author_thumbnail( $guest_author, $size, $class = null ) {
981
  // See if the guest author has an avatar
1007
  */
1008
  function get_guest_author_fields( $groups = 'all' ) {
1009
 
1010
+ $groups = (array) $groups;
1011
  $global_fields = array(
1012
+ // Hidden (included in object, no UI elements)
1013
+ array(
1014
+ 'key' => 'ID',
1015
+ 'label' => __( 'ID', 'co-authors-plus' ),
1016
+ 'group' => 'hidden',
1017
+ 'input' => 'hidden',
1018
+ ),
1019
+ // Name
1020
+ array(
1021
+ 'key' => 'display_name',
1022
+ 'label' => __( 'Display Name', 'co-authors-plus' ),
1023
+ 'group' => 'name',
1024
+ 'required' => true,
1025
+ ),
1026
+ array(
1027
+ 'key' => 'first_name',
1028
+ 'label' => __( 'First Name', 'co-authors-plus' ),
1029
+ 'group' => 'name',
1030
+ ),
1031
+ array(
1032
+ 'key' => 'last_name',
1033
+ 'label' => __( 'Last Name', 'co-authors-plus' ),
1034
+ 'group' => 'name',
1035
+ ),
1036
+ array(
1037
+ 'key' => 'user_login',
1038
+ 'label' => __( 'Slug', 'co-authors-plus' ),
1039
+ 'group' => 'slug',
1040
+ 'required' => true,
1041
+ ),
1042
+ // Contact info
1043
+ array(
1044
+ 'key' => 'user_email',
1045
+ 'label' => __( 'E-mail', 'co-authors-plus' ),
1046
+ 'group' => 'contact-info',
1047
+ 'input' => 'email',
1048
+ ),
1049
+ array(
1050
+ 'key' => 'linked_account',
1051
+ 'label' => __( 'Linked Account', 'co-authors-plus' ),
1052
+ 'group' => 'slug',
1053
+ ),
1054
+ array(
1055
+ 'key' => 'website',
1056
+ 'label' => __( 'Website', 'co-authors-plus' ),
1057
+ 'group' => 'contact-info',
1058
+ 'input' => 'url',
1059
+ ),
1060
+ array(
1061
+ 'key' => 'aim',
1062
+ 'label' => __( 'AIM', 'co-authors-plus' ),
1063
+ 'group' => 'contact-info',
1064
+ ),
1065
+ array(
1066
+ 'key' => 'yahooim',
1067
+ 'label' => __( 'Yahoo IM', 'co-authors-plus' ),
1068
+ 'group' => 'contact-info',
1069
+ ),
1070
+ array(
1071
+ 'key' => 'jabber',
1072
+ 'label' => __( 'Jabber / Google Talk', 'co-authors-plus' ),
1073
+ 'group' => 'contact-info',
1074
+ ),
1075
+ array(
1076
+ 'key' => 'description',
1077
+ 'label' => __( 'Biographical Info', 'co-authors-plus' ),
1078
+ 'group' => 'about',
1079
+ 'sanitize_function' => 'wp_filter_post_kses',
1080
+ ),
1081
+ );
1082
  $fields_to_return = array();
1083
  foreach ( $global_fields as $single_field ) {
1084
  if ( in_array( $single_field['group'], $groups ) || 'all' === $groups[0] && 'hidden' !== $single_field['group'] ) {
1145
  global $wpdb;
1146
 
1147
  $cache_key = 'all-linked-accounts';
1148
+ $retval = wp_cache_get( $cache_key, self::$cache_group );
1149
 
1150
  if ( true === $force || false === $retval ) {
1151
  $user_logins = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value !=''", $this->get_post_meta_key( 'linked_account' ) ) );
1152
+ $users = array();
1153
  foreach ( $user_logins as $user_login ) {
1154
  $user = get_user_by( 'login', $user_login );
1155
  if ( ! $user ) {
1156
  continue;
1157
  }
1158
  $users[] = array(
1159
+ 'ID' => $user->ID,
1160
+ 'user_login' => $user->user_login,
1161
+ );
1162
  }
1163
  $retval = $users;
1164
  wp_cache_set( $cache_key, $retval, self::$cache_group );
1216
 
1217
  if ( 'post_name' == $key ) {
1218
  $value_key = 'user_nicename';
1219
+ } elseif ( 'login' == $key ) {
1220
  $value_key = 'user_login';
1221
  }
1222
 
1258
 
1259
  // Create the primary post object
1260
  $new_post = array(
1261
+ 'post_title' => $args['display_name'],
1262
+ 'post_name' => sanitize_title( $this->get_post_meta_key( $args['user_login'] ) ),
1263
+ 'post_type' => $this->post_type,
1264
+ );
1265
+ $post_id = wp_insert_post( $new_post, true );
1266
  if ( is_wp_error( $post_id ) ) {
1267
  return $post_id;
1268
  }
1278
  }
1279
 
1280
  // Attach the avatar / featured image.
1281
+ if ( ! empty( $args['avatar'] ) ) {
1282
+ set_post_thumbnail( $post_id, $args['avatar'] );
1283
  }
1284
 
1285
  // Make sure the author term exists and that we're assigning it to this post type
1298
  *
1299
  * @since 3.0
1300
  *
1301
+ * @param int $post_id The ID for the guest author profile
1302
  * @param string $reassign_to User login value for the co-author to reassign posts to
1303
  * @return bool|WP_Error $success True on success, WP_Error on a failure
1304
  */
1328
  $reassign_to_term = $coauthors_plus->get_author_term( $reassign_to_author );
1329
  // In the case where the guest author and its linked account shared the same term, we don't want to reassign
1330
  if ( $guest_author_term->term_id != $reassign_to_term->term_id ) {
1331
+ wp_delete_term(
1332
+ $guest_author_term->term_id,
1333
+ $coauthors_plus->coauthor_taxonomy,
1334
+ array(
1335
+ 'default' => $reassign_to_term->term_id,
1336
+ 'force_default' => true,
1337
+ )
1338
+ );
1339
  }
1340
  } else {
1341
  wp_delete_term( $guest_author_term->term_id, $coauthors_plus->coauthor_taxonomy );
1380
  $guest_author['linked_account'] = $guest_author['user_login'];
1381
  if ( ! empty( $guest_author['display_name'] ) && $guest_author['display_name'] != $guest_author['user_login'] ) {
1382
  $guest_author['user_login'] = sanitize_title( $guest_author['display_name'] );
1383
+ } elseif ( ! empty( $guest_author['first_name'] ) && ! empty( $guest_author['last_name'] ) ) {
1384
  $guest_author['user_login'] = sanitize_title( $guest_author['first_name'] . ' ' . $guest_author['last_name'] );
1385
  }
1386
 
1412
  *
1413
  * @since 3.0
1414
  *
1415
+ * @param array $actions The existing actions to perform on a user
1416
  * @param object $user_object A WP_User object
1417
  * @return array $actions Modified actions
1418
  */
1424
 
1425
  $new_actions = array();
1426
  if ( $guest_author = $this->get_guest_author_by( 'linked_account', $user_object->user_login ) ) {
1427
+ $edit_guest_author_link = get_edit_post_link( $guest_author->ID );
1428
  $new_actions['edit-guest-author'] = '<a href="' . esc_url( $edit_guest_author_link ) . '">' . __( 'Edit Profile', 'co-authors-plus' ) . '</a>';
1429
  } else {
1430
+ $query_args = array(
1431
+ 'action' => 'cap-create-guest-author',
1432
+ 'user_id' => $user_object->ID,
1433
+ 'nonce' => wp_create_nonce( 'create-guest-author' ),
1434
+ );
1435
  $create_guest_author_link = add_query_arg( array_map( 'rawurlencode', $query_args ), admin_url( $this->parent_page ) );
1436
  if ( apply_filters( 'coauthors_show_create_profile_user_link', false ) ) {
1437
  $new_actions['create-guest-author'] = '<a href="' . esc_url( $create_guest_author_link ) . '">' . __( 'Create Profile', 'co-authors-plus' ) . '</a>';
1527
  if ( '' == $permalink_structure ) {
1528
  $link = home_url( "?feed=$feed&amp;author=" . $author->ID );
1529
  } else {
1530
+ $link = get_author_posts_url( $author->ID );
1531
  $feed_link = ( get_default_feed() === $feed ) ? 'feed' : "feed/$feed";
1532
+ $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' );
1533
  }
1534
 
1535
  return $link;
1555
  * @since 3.3.1
1556
  *
1557
  * @param string $email_address The guest author email address.
1558
+ * @return array An array of personal data.
1559
  */
1560
  public function personal_data_exporter( $email_address ) {
1561
  $email_address = trim( $email_address );
1572
  }
1573
 
1574
  $author_data = array(
1575
+ 'ID' => __( 'ID', 'co-authors-plus' ),
1576
+ 'user_login' => __( 'Login Name', 'co-authors-plus' ),
1577
+ 'display_name' => __( 'Display Name', 'co-authors-plus' ),
1578
+ 'user_email' => __( 'Email', 'co-authors-plus' ),
1579
+ 'first_name' => __( 'First Name', 'co-authors-plus' ),
1580
+ 'last_name' => __( 'Last Name', 'co-authors-plus' ),
1581
+ 'website' => __( 'Website', 'co-authors-plus' ),
1582
+ 'aim' => __( 'AIM', 'co-authors-plus' ),
1583
+ 'yahooim' => __( 'Yahoo IM', 'co-authors-plus' ),
1584
+ 'jabber' => __( 'Jabber / Google Talk', 'co-authors-plus' ),
1585
+ 'description' => __( 'Biographical Info', 'co-authors-plus' ),
1586
  );
1587
 
1588
  $author_data_to_export = array();
1607
  * @param int $author->ID The guest author ID
1608
  * @param string $email_address The guest author email address
1609
  */
1610
+ $extra_data = apply_filters( 'coauthors_guest_author_personal_export_extra_data', array(), $author->ID, $email_address );
1611
 
1612
  if ( is_array( $extra_data ) && ! empty( $extra_data ) ) {
1613
  $author_data_to_export = array_merge( $author_data_to_export, $extra_data );
php/class-coauthors-template-filters.php CHANGED
@@ -12,7 +12,7 @@ class CoAuthors_Template_Filters {
12
 
13
  // Add support for Guest Authors in RSS feeds.
14
  add_filter( 'the_author', array( $this, 'filter_the_author_rss' ), 15 ); // Override CoAuthors_Template_Filters::filter_the_author for RSS feeds
15
- add_action( 'rss2_item', array( $this, 'action_add_rss_guest_authors' ) );
16
  }
17
 
18
  function filter_the_author() {
12
 
13
  // Add support for Guest Authors in RSS feeds.
14
  add_filter( 'the_author', array( $this, 'filter_the_author_rss' ), 15 ); // Override CoAuthors_Template_Filters::filter_the_author for RSS feeds
15
+ add_action( 'rss2_item', array( $this, 'action_add_rss_guest_authors' ) );
16
  }
17
 
18
  function filter_the_author() {
php/class-coauthors-wp-list-table.php CHANGED
@@ -1,40 +1,43 @@
1
  <?php
2
- //Our class extends the WP_List_Table class, so we need to make sure that it's there
3
 
4
- require_once( ABSPATH . 'wp-admin/includes/screen.php' );
5
- require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
6
 
7
  /**
8
  * List all of the available Co-Authors within the system
9
  */
10
  class CoAuthors_WP_List_Table extends WP_List_Table {
11
 
12
- var $is_search = false;
 
 
13
 
14
  function __construct() {
15
  if ( ! empty( $_REQUEST['s'] ) ) {
16
  $this->is_search = true;
17
  }
18
 
19
- parent::__construct( array(
20
- 'plural' => __( 'Co-Authors', 'co-authors-plus' ),
21
- 'singular' => __( 'Co-Author', 'co-authors-plus' ),
22
- ) );
 
 
23
  }
24
-
25
  /**
26
  * Perform Co-Authors Query
27
  */
28
  function prepare_items() {
29
  global $coauthors_plus;
30
 
31
- $columns = $this->get_columns();
32
- $hidden = array();
33
- $sortable = array(
34
- 'display_name' => array( 'display_name', 'ASC' ),
35
- 'first_name' => array( 'first_name', 'ASC' ),
36
- 'last_name' => array( 'last_name', 'ASC' ),
37
- );
38
  $_sortable = apply_filters( 'coauthors_guest_author_sortable_columns', $this->get_sortable_columns() );
39
 
40
  foreach ( (array) $_sortable as $id => $data ) {
@@ -52,17 +55,17 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
52
 
53
  $this->_column_headers = array( $columns, $hidden, $sortable );
54
 
55
- $paged = ( isset( $_REQUEST['paged'] ) ) ? intval( $_REQUEST['paged'] ) : 1;
56
  $per_page = 20;
57
 
58
  $args = array(
59
- 'paged' => $paged,
60
- 'posts_per_page' => $per_page,
61
- 'post_type' => $coauthors_plus->guest_authors->post_type,
62
- 'post_status' => 'any',
63
- 'orderby' => 'title',
64
- 'order' => 'ASC',
65
- );
66
 
67
  $args = apply_filters( 'coauthors_guest_author_query_args', $args );
68
 
@@ -73,7 +76,7 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
73
  break;
74
  case 'first_name':
75
  case 'last_name':
76
- $args['orderby'] = 'meta_value';
77
  $args['meta_key'] = $coauthors_plus->guest_authors->get_post_meta_key( $_REQUEST['orderby'] );
78
  break;
79
  }
@@ -83,10 +86,10 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
83
  }
84
 
85
  $this->filters = array(
86
- 'show-all' => __( 'Show all', 'co-authors-plus' ),
87
- 'with-linked-account' => __( 'With linked account', 'co-authors-plus' ),
88
- 'without-linked-account' => __( 'Without linked account', 'co-authors-plus' ),
89
- );
90
 
91
  if ( isset( $_REQUEST['filter'] ) && array_key_exists( $_REQUEST['filter'], $this->filters ) ) {
92
  $this->active_filter = sanitize_key( $_REQUEST['filter'] );
@@ -94,16 +97,30 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
94
  $this->active_filter = 'show-all';
95
  }
96
 
 
97
  switch ( $this->active_filter ) {
98
  case 'with-linked-account':
 
 
 
 
 
 
 
 
99
  case 'without-linked-account':
100
- $args['meta_key'] = $coauthors_plus->guest_authors->get_post_meta_key( 'linked_account' );
101
- if ( 'with-linked-account' == $this->active_filter ) {
102
- $args['meta_compare'] = '!=';
103
- } else {
104
- $args['meta_compare'] = '=';
105
- }
106
- $args['meta_value'] = '0';
 
 
 
 
 
107
  break;
108
  }
109
 
@@ -112,7 +129,7 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
112
  }
113
 
114
  $author_posts = new WP_Query( $args );
115
- $items = array();
116
  foreach ( $author_posts->get_posts() as $author_post ) {
117
  $items[] = $coauthors_plus->guest_authors->get_guest_author_by( 'ID', $author_post->ID );
118
  }
@@ -123,16 +140,20 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
123
 
124
  $this->items = $items;
125
 
126
- $this->set_pagination_args( array(
127
- 'total_items' => $author_posts->found_posts,
128
- 'per_page' => $per_page,
129
- ) );
 
 
130
  }
131
 
132
  function filter_query_for_search( $where ) {
133
  global $wpdb;
134
- $var = '%' . sanitize_text_field( $_REQUEST['s'] ) . '%';
135
- $where .= $wpdb->prepare( ' AND (post_title LIKE %s OR post_name LIKE %s )', $var, $var );
 
 
136
  return $where;
137
  }
138
 
@@ -148,13 +169,13 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
148
  */
149
  function get_columns() {
150
  $columns = array(
151
- 'display_name' => __( 'Display Name', 'co-authors-plus' ),
152
- 'first_name' => __( 'First Name', 'co-authors-plus' ),
153
- 'last_name' => __( 'Last Name', 'co-authors-plus' ),
154
- 'user_email' => __( 'E-mail', 'co-authors-plus' ),
155
- 'linked_account' => __( 'Linked Account', 'co-authors-plus' ),
156
- 'posts' => __( 'Posts', 'co-authors-plus' ),
157
- );
158
 
159
  $columns = apply_filters( 'coauthors_guest_author_manage_columns', $columns );
160
  return $columns;
@@ -165,8 +186,8 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
165
  */
166
  function single_row( $item ) {
167
  static $alternate_class = '';
168
- $alternate_class = ( '' === $alternate_class ? ' alternate' : '' );
169
- $row_class = 'guest-author-static' . $alternate_class . '"';
170
 
171
  echo '<tr id="' . esc_attr( 'guest-author-' . $item->ID ) . '" class="' . esc_attr( $row_class ) . '">';
172
  $this->single_row_columns( $item );
@@ -183,11 +204,11 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
183
  case 'last_name':
184
  return $item->$column_name;
185
  case 'user_email':
186
- return '<a href="' . esc_attr( 'mailto:' . $item->user_email ) . '">' . esc_html( $item->user_email ) . '</a>';
187
 
188
  default:
189
  do_action( 'coauthors_guest_author_custom_columns', $column_name, $item->ID );
190
- break;
191
  }
192
  }
193
 
@@ -196,14 +217,14 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
196
  */
197
  function column_display_name( $item ) {
198
 
199
- $item_edit_link = get_edit_post_link( $item->ID );
200
- $args = array(
201
- 'action' => 'delete',
202
- 'id' => $item->ID,
203
- '_wpnonce' => wp_create_nonce( 'guest-author-delete' ),
204
- );
205
  $item_delete_link = add_query_arg( array_map( 'rawurlencode', $args ), menu_page_url( 'view-guest-authors', false ) );
206
- $item_view_link = get_author_posts_url( $item->ID, $item->user_nicename );
207
 
208
  $output = '';
209
 
@@ -223,8 +244,8 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
223
  $actions['delete'] = '<a href="' . esc_url( $item_delete_link ) . '">' . __( 'Delete', 'co-authors-plus' ) . '</a>';
224
  }
225
  $actions['view'] = '<a href="' . esc_url( $item_view_link ) . '">' . __( 'View Posts', 'co-authors-plus' ) . '</a>';
226
- $actions = apply_filters( 'coauthors_guest_author_row_actions', $actions, $item );
227
- $output .= $this->row_actions( $actions, false );
228
 
229
  return $output;
230
  }
@@ -252,14 +273,6 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
252
  global $coauthors_plus;
253
  $count = $coauthors_plus->get_guest_author_post_count( $item );
254
 
255
- if ( ! empty( $item->linked_account ) ) {
256
- global $coauthors_plus;
257
- // Add user term count to guest author term count.
258
- $term = get_term_by( 'slug', 'cap-' . $item->linked_account, $coauthors_plus->coauthor_taxonomy );
259
- if ( is_object( $term ) ) {
260
- $count = $count + $term->count;
261
- }
262
- }
263
  return '<a href="' . esc_url( add_query_arg( 'author_name', rawurlencode( $item->user_login ), admin_url( 'edit.php' ) ) ) . '">' . $count . '</a>';
264
  }
265
 
@@ -268,18 +281,21 @@ class CoAuthors_WP_List_Table extends WP_List_Table {
268
  */
269
  function extra_tablenav( $which ) {
270
 
271
- ?><div class="alignleft actions"><?php
272
- if ( 'top' == $which ) {
273
- if ( ! empty( $this->filters ) ) {
274
- echo '<select name="filter">';
275
- foreach ( $this->filters as $key => $value ) {
276
- echo '<option value="' . esc_attr( $key ) . '" ' . selected( $this->active_filter, $key, false ) . '>' . esc_attr( $value ) . '</option>';
 
 
 
 
 
277
  }
278
- echo '</select>';
279
- }
280
- submit_button( __( 'Filter', 'co-authors-plus' ), 'secondary', false, false );
281
- }
282
- ?></div><?php
283
  }
284
 
285
  function display() {
1
  <?php
2
+ // Our class extends the WP_List_Table class, so we need to make sure that it's there
3
 
4
+ require_once ABSPATH . 'wp-admin/includes/screen.php';
5
+ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
6
 
7
  /**
8
  * List all of the available Co-Authors within the system
9
  */
10
  class CoAuthors_WP_List_Table extends WP_List_Table {
11
 
12
+ var $is_search = false;
13
+ var $filters = array();
14
+ var $active_filter = '';
15
 
16
  function __construct() {
17
  if ( ! empty( $_REQUEST['s'] ) ) {
18
  $this->is_search = true;
19
  }
20
 
21
+ parent::__construct(
22
+ array(
23
+ 'plural' => __( 'Co-Authors', 'co-authors-plus' ),
24
+ 'singular' => __( 'Co-Author', 'co-authors-plus' ),
25
+ )
26
+ );
27
  }
 
28
  /**
29
  * Perform Co-Authors Query
30
  */
31
  function prepare_items() {
32
  global $coauthors_plus;
33
 
34
+ $columns = $this->get_columns();
35
+ $hidden = array();
36
+ $sortable = array(
37
+ 'display_name' => array( 'display_name', 'ASC' ),
38
+ 'first_name' => array( 'first_name', 'ASC' ),
39
+ 'last_name' => array( 'last_name', 'ASC' ),
40
+ );
41
  $_sortable = apply_filters( 'coauthors_guest_author_sortable_columns', $this->get_sortable_columns() );
42
 
43
  foreach ( (array) $_sortable as $id => $data ) {
55
 
56
  $this->_column_headers = array( $columns, $hidden, $sortable );
57
 
58
+ $paged = ( isset( $_REQUEST['paged'] ) ) ? intval( $_REQUEST['paged'] ) : 1;
59
  $per_page = 20;
60
 
61
  $args = array(
62
+ 'paged' => $paged,
63
+ 'posts_per_page' => $per_page,
64
+ 'post_type' => $coauthors_plus->guest_authors->post_type,
65
+ 'post_status' => 'any',
66
+ 'orderby' => 'title',
67
+ 'order' => 'ASC',
68
+ );
69
 
70
  $args = apply_filters( 'coauthors_guest_author_query_args', $args );
71
 
76
  break;
77
  case 'first_name':
78
  case 'last_name':
79
+ $args['orderby'] = 'meta_value';
80
  $args['meta_key'] = $coauthors_plus->guest_authors->get_post_meta_key( $_REQUEST['orderby'] );
81
  break;
82
  }
86
  }
87
 
88
  $this->filters = array(
89
+ 'show-all' => __( 'Show all', 'co-authors-plus' ),
90
+ 'with-linked-account' => __( 'With linked account', 'co-authors-plus' ),
91
+ 'without-linked-account' => __( 'Without linked account', 'co-authors-plus' ),
92
+ );
93
 
94
  if ( isset( $_REQUEST['filter'] ) && array_key_exists( $_REQUEST['filter'], $this->filters ) ) {
95
  $this->active_filter = sanitize_key( $_REQUEST['filter'] );
97
  $this->active_filter = 'show-all';
98
  }
99
 
100
+ $key = $coauthors_plus->guest_authors->get_post_meta_key( 'linked_account' );
101
  switch ( $this->active_filter ) {
102
  case 'with-linked-account':
103
+ $args['meta_query'] = array(
104
+ array(
105
+ 'key' => $key,
106
+ 'compare' => '!=',
107
+ 'value' => '',
108
+ ),
109
+ );
110
+ break;
111
  case 'without-linked-account':
112
+ $args['meta_query'] = array(
113
+ 'relation' => 'OR',
114
+ array(
115
+ 'key' => $key,
116
+ 'compare' => 'NOT EXISTS',
117
+ ),
118
+ array(
119
+ 'key' => $key,
120
+ 'compare' => '=',
121
+ 'value' => '',
122
+ ),
123
+ );
124
  break;
125
  }
126
 
129
  }
130
 
131
  $author_posts = new WP_Query( $args );
132
+ $items = array();
133
  foreach ( $author_posts->get_posts() as $author_post ) {
134
  $items[] = $coauthors_plus->guest_authors->get_guest_author_by( 'ID', $author_post->ID );
135
  }
140
 
141
  $this->items = $items;
142
 
143
+ $this->set_pagination_args(
144
+ array(
145
+ 'total_items' => $author_posts->found_posts,
146
+ 'per_page' => $per_page,
147
+ )
148
+ );
149
  }
150
 
151
  function filter_query_for_search( $where ) {
152
  global $wpdb;
153
+ if ( isset( $_REQUEST['s'] ) ) {
154
+ $var = '%' . sanitize_text_field( $_REQUEST['s'] ) . '%';
155
+ $where .= $wpdb->prepare( ' AND (post_title LIKE %s OR post_name LIKE %s )', $var, $var );
156
+ }
157
  return $where;
158
  }
159
 
169
  */
170
  function get_columns() {
171
  $columns = array(
172
+ 'display_name' => __( 'Display Name', 'co-authors-plus' ),
173
+ 'first_name' => __( 'First Name', 'co-authors-plus' ),
174
+ 'last_name' => __( 'Last Name', 'co-authors-plus' ),
175
+ 'user_email' => __( 'E-mail', 'co-authors-plus' ),
176
+ 'linked_account' => __( 'Linked Account', 'co-authors-plus' ),
177
+ 'posts' => __( 'Posts', 'co-authors-plus' ),
178
+ );
179
 
180
  $columns = apply_filters( 'coauthors_guest_author_manage_columns', $columns );
181
  return $columns;
186
  */
187
  function single_row( $item ) {
188
  static $alternate_class = '';
189
+ $alternate_class = ( '' === $alternate_class ? ' alternate' : '' );
190
+ $row_class = 'guest-author-static' . $alternate_class . '"';
191
 
192
  echo '<tr id="' . esc_attr( 'guest-author-' . $item->ID ) . '" class="' . esc_attr( $row_class ) . '">';
193
  $this->single_row_columns( $item );
204
  case 'last_name':
205
  return $item->$column_name;
206
  case 'user_email':
207
+ return '<a href="' . esc_url( 'mailto:' . $item->user_email ) . '">' . esc_html( $item->user_email ) . '</a>';
208
 
209
  default:
210
  do_action( 'coauthors_guest_author_custom_columns', $column_name, $item->ID );
211
+ break;
212
  }
213
  }
214
 
217
  */
218
  function column_display_name( $item ) {
219
 
220
+ $item_edit_link = get_edit_post_link( $item->ID );
221
+ $args = array(
222
+ 'action' => 'delete',
223
+ 'id' => $item->ID,
224
+ '_wpnonce' => wp_create_nonce( 'guest-author-delete' ),
225
+ );
226
  $item_delete_link = add_query_arg( array_map( 'rawurlencode', $args ), menu_page_url( 'view-guest-authors', false ) );
227
+ $item_view_link = get_author_posts_url( $item->ID, $item->user_nicename );
228
 
229
  $output = '';
230
 
244
  $actions['delete'] = '<a href="' . esc_url( $item_delete_link ) . '">' . __( 'Delete', 'co-authors-plus' ) . '</a>';
245
  }
246
  $actions['view'] = '<a href="' . esc_url( $item_view_link ) . '">' . __( 'View Posts', 'co-authors-plus' ) . '</a>';
247
+ $actions = apply_filters( 'coauthors_guest_author_row_actions', $actions, $item );
248
+ $output .= $this->row_actions( $actions, false );
249
 
250
  return $output;
251
  }
273
  global $coauthors_plus;
274
  $count = $coauthors_plus->get_guest_author_post_count( $item );
275
 
 
 
 
 
 
 
 
 
276
  return '<a href="' . esc_url( add_query_arg( 'author_name', rawurlencode( $item->user_login ), admin_url( 'edit.php' ) ) ) . '">' . $count . '</a>';
277
  }
278
 
281
  */
282
  function extra_tablenav( $which ) {
283
 
284
+ ?><div class="alignleft actions">
285
+ <?php
286
+ if ( 'top' == $which ) {
287
+ if ( ! empty( $this->filters ) ) {
288
+ echo '<select name="filter">';
289
+ foreach ( $this->filters as $key => $value ) {
290
+ echo '<option value="' . esc_attr( $key ) . '" ' . selected( $this->active_filter, $key, false ) . '>' . esc_attr( $value ) . '</option>'; // phpcs:ignore
291
+ }
292
+ echo '</select>';
293
+ submit_button( __( 'Filter', 'co-authors-plus' ), 'secondary', false, false );
294
+ }
295
  }
296
+ ?>
297
+ </div>
298
+ <?php
 
 
299
  }
300
 
301
  function display() {
php/class-wp-cli.php CHANGED
@@ -22,13 +22,13 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
22
 
23
  $defaults = array(
24
  // There are no arguments at this time
25
- );
26
  $this->args = wp_parse_args( $assoc_args, $defaults );
27
 
28
- $users = get_users();
29
- $created = 0;
30
- $skipped = 0;
31
- $progress = \WP_CLI\Utils\make_progress_bar( 'Processing guest authors...', count ( $users ) );
32
  foreach ( $users as $user ) {
33
 
34
  $result = $coauthors_plus->guest_authors->create_guest_author_from_user_id( $user->ID );
@@ -54,21 +54,21 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
54
  global $coauthors_plus, $wp_post_types;
55
 
56
  // Cache these to prevent repeated lookups
57
- $authors = array();
58
  $author_terms = array();
59
 
60
  $args = array(
61
- 'order' => 'ASC',
62
- 'orderby' => 'ID',
63
- 'post_type' => $coauthors_plus->supported_post_types,
64
- 'posts_per_page' => 100,
65
- 'paged' => 1,
66
- 'update_meta_cache' => false,
67
- );
68
 
69
- $posts = new WP_Query( $args );
70
- $affected = 0;
71
- $count = 0;
72
  $total_posts = $posts->found_posts;
73
  WP_CLI::line( "Now inspecting or updating {$posts->found_posts} total posts." );
74
  while ( $posts->post_count ) {
@@ -87,10 +87,10 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
87
  continue;
88
  }
89
 
90
- $author = ( ! empty( $authors[ $single_post->post_author ] ) ) ? $authors[ $single_post->post_author ] : get_user_by( 'id', $single_post->post_author );
91
  $authors[ $single_post->post_author ] = $author;
92
 
93
- $author_term = ( ! empty( $author_terms[ $single_post->post_author ] ) ) ? $author_terms[ $single_post->post_author ] : $coauthors_plus->update_author_term( $author );
94
  $author_terms[ $single_post->post_author ] = $author_term;
95
 
96
  wp_set_post_terms( $single_post->ID, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy );
@@ -126,26 +126,26 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
126
  public function assign_coauthors( $args, $assoc_args ) {
127
  global $coauthors_plus;
128
 
129
- $defaults = array(
130
- 'meta_key' => '_original_import_author',
131
- 'post_type' => 'post',
132
- 'order' => 'ASC',
133
- 'orderby' => 'ID',
134
- 'posts_per_page' => 100,
135
- 'paged' => 1,
136
- 'append_coauthors' => false,
137
- );
138
  $this->args = wp_parse_args( $assoc_args, $defaults );
139
 
140
  // For global use and not a part of WP_Query
141
  $append_coauthors = $this->args['append_coauthors'];
142
  unset( $this->args['append_coauthors'] );
143
 
144
- $posts_total = 0;
145
  $posts_already_associated = 0;
146
- $posts_missing_coauthor = 0;
147
- $posts_associated = 0;
148
- $missing_coauthors = array();
149
 
150
  $posts = new WP_Query( $this->args );
151
  while ( $posts->post_count ) {
@@ -154,7 +154,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
154
  $posts_total++;
155
 
156
  // See if the value in the post meta field is the same as any of the existing coauthors
157
- $original_author = get_post_meta( $single_post->ID, $this->args['meta_key'], true );
158
  $existing_coauthors = get_coauthors( $single_post->ID );
159
  $already_associated = false;
160
  foreach ( $existing_coauthors as $existing_coauthor ) {
@@ -215,13 +215,13 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
215
  public function assign_user_to_coauthor( $args, $assoc_args ) {
216
  global $coauthors_plus, $wpdb;
217
 
218
- $defaults = array(
219
- 'user_login' => '',
220
- 'coauthor' => '',
221
- );
222
  $assoc_args = wp_parse_args( $assoc_args, $defaults );
223
 
224
- $user = get_user_by( 'login', $assoc_args['user_login'] );
225
  $coauthor = $coauthors_plus->get_coauthor_by( 'login', $assoc_args['coauthor'] );
226
 
227
  if ( ! $user ) {
@@ -233,21 +233,23 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
233
  }
234
 
235
  $post_types = implode( "','", $coauthors_plus->supported_post_types );
236
- $posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author=%d AND post_type IN ('$post_types')", $user->ID ) );
237
- $affected = 0;
238
  foreach ( $posts as $post_id ) {
239
  $coauthors = cap_get_coauthor_terms_for_post( $post_id );
240
  if ( ! empty( $coauthors ) ) {
241
- WP_CLI::line( sprintf(
242
- __( 'Skipping - Post #%d already has co-authors assigned: %s', 'co-authors-plus' ),
243
- $post_id,
244
- implode( ', ', wp_list_pluck( $coauthors, 'slug' ) )
245
- ) );
 
 
246
  continue;
247
  }
248
 
249
  $coauthors_plus->add_coauthors( $post_id, array( $coauthor->user_login ) );
250
- WP_CLI::line( sprintf( __( "Updating - Adding %s's byline to post #%d", 'co-authors-plus' ), $coauthor->user_login, $post_id ) );
251
  $affected++;
252
  if ( $affected && 0 === $affected % 100 ) {
253
  sleep( 2 );
@@ -274,22 +276,22 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
274
  public function reassign_terms( $args, $assoc_args ) {
275
  global $coauthors_plus;
276
 
277
- $defaults = array(
278
- 'author_mapping' => null,
279
- 'old_term' => null,
280
- 'new_term' => null,
281
- );
282
  $this->args = wp_parse_args( $assoc_args, $defaults );
283
 
284
  $author_mapping = $this->args['author_mapping'];
285
- $old_term = $this->args['old_term'];
286
- $new_term = $this->args['new_term'];
287
 
288
  // Get the reassignment data
289
  if ( $author_mapping && file_exists( $author_mapping ) ) {
290
- require_once( $author_mapping );
291
  $authors_to_migrate = $cli_user_map;
292
- } else if ( $author_mapping ) {
293
  WP_CLI::error( "author_mapping doesn't exist: " . $author_mapping );
294
  exit;
295
  }
@@ -297,17 +299,17 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
297
  // Alternate reassigment approach
298
  if ( $old_term && $new_term ) {
299
  $authors_to_migrate = array(
300
- $old_term => $new_term,
301
- );
302
  }
303
 
304
  // For each author to migrate, check whether the term exists,
305
  // whether the target term exists, and only do the migration if both are met
306
  $results = (object) array(
307
- 'old_term_missing' => 0,
308
- 'new_term_exists' => 0,
309
- 'success' => 0,
310
- );
311
  foreach ( $authors_to_migrate as $old_user => $new_user ) {
312
 
313
  if ( is_numeric( $new_user ) ) {
@@ -329,16 +331,16 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
329
  if ( is_object( $new_term ) ) {
330
  WP_CLI::line( "Success: There's already a '{$new_user}' term for '{$old_user}'. Reassigning {$old_term->count} posts and then deleting the term" );
331
  $args = array(
332
- 'default' => $new_term->term_id,
333
- 'force_default' => true,
334
- );
335
  wp_delete_term( $old_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
336
  $results->new_term_exists++;
337
  } else {
338
  $args = array(
339
- 'slug' => $new_user,
340
- 'name' => $new_user,
341
- );
342
  wp_update_term( $old_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
343
  WP_CLI::line( "Success: Converted '{$old_user}' term to '{$new_user}'" );
344
  $results->success++;
@@ -366,13 +368,13 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
366
  public function rename_coauthor( $args, $assoc_args ) {
367
  global $coauthors_plus, $wpdb;
368
 
369
- $defaults = array(
370
- 'from' => null,
371
- 'to' => null,
372
- );
373
  $assoc_args = array_merge( $defaults, $assoc_args );
374
 
375
- $to_userlogin = $assoc_args['to'];
376
  $to_userlogin_prefixed = 'cap-' . $to_userlogin;
377
 
378
  $orig_coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $assoc_args['from'] );
@@ -392,9 +394,9 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
392
 
393
  WP_CLI::line( "Renaming {$orig_term->name} to {$to_userlogin}" );
394
  $rename_args = array(
395
- 'name' => $to_userlogin,
396
- 'slug' => $to_userlogin_prefixed,
397
- );
398
  wp_update_term( $orig_term->term_id, $coauthors_plus->coauthor_taxonomy, $rename_args );
399
 
400
  if ( 'guest-author' == $orig_coauthor->type ) {
@@ -421,19 +423,19 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
421
  $defaults = array(
422
  'from' => null,
423
  'to' => null,
424
- 'post_type' => 'post',
425
- 'dry' => false,
426
  );
427
 
428
  $assoc_args = array_merge( $defaults, $assoc_args );
429
 
430
- $dry = $assoc_args['dry'];
431
 
432
- $from_userlogin = $assoc_args['from'];
433
- $to_userlogin = $assoc_args['to'];
434
 
435
- $from_userlogin_prefixed = 'cap-' . $from_userlogin;
436
- $to_userlogin_prefixed = 'cap-' . $to_userlogin;
437
 
438
  $orig_coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $from_userlogin );
439
 
@@ -454,16 +456,16 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
454
  WP_CLI::line( "Swapping authorship from {$from_userlogin} to {$to_userlogin}" );
455
 
456
  $query_args = array(
457
- 'post_type' => $assoc_args['post_type'],
458
- 'order' => 'ASC',
459
- 'orderby' => 'ID',
460
- 'posts_per_page' => 100,
461
- 'paged' => 1,
462
- 'tax_query' => array(
463
  array(
464
- 'taxonomy' => $coauthors_plus->coauthor_taxonomy,
465
- 'field' => 'slug',
466
- 'terms' => array( $from_userlogin_prefixed ),
467
  ),
468
  ),
469
  );
@@ -534,16 +536,16 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
534
  public function list_posts_without_terms( $args, $assoc_args ) {
535
  global $coauthors_plus;
536
 
537
- $defaults = array(
538
- 'post_type' => 'post',
539
- 'order' => 'ASC',
540
- 'orderby' => 'ID',
541
- 'year' => '',
542
- 'posts_per_page' => 300,
543
- 'paged' => 1,
544
- 'no_found_rows' => true,
545
- 'update_meta_cache' => false,
546
- );
547
  $this->args = wp_parse_args( $assoc_args, $defaults );
548
 
549
  $posts = new WP_Query( $this->args );
@@ -554,11 +556,11 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
554
  $terms = cap_get_coauthor_terms_for_post( $single_post->ID );
555
  if ( empty( $terms ) ) {
556
  $saved = array(
557
- $single_post->ID,
558
- addslashes( $single_post->post_title ),
559
- get_permalink( $single_post->ID ),
560
- $single_post->post_date,
561
- );
562
  WP_CLI::line( '"' . implode( '","', $saved ) . '"' );
563
  }
564
  }
@@ -595,7 +597,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
595
  if ( $prefixed_term = get_term_by( 'slug', 'cap-' . $author_term->slug, $coauthors_plus->coauthor_taxonomy ) ) {
596
  WP_CLI::line( "Term {$author_term->slug} ({$author_term->term_id}) has a new term too: $prefixed_term->slug ($prefixed_term->term_id). Merging" );
597
  $args = array(
598
- 'default' => $author_term->term_id,
599
  'force_default' => true,
600
  );
601
  wp_delete_term( $prefixed_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
@@ -604,8 +606,8 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
604
  // Term isn't prefixed, doesn't have a sibling, and should be updated
605
  WP_CLI::line( "Term {$author_term->slug} ({$author_term->term_id}) isn't prefixed, adding one" );
606
  $args = array(
607
- 'slug' => 'cap-' . $author_term->slug,
608
- );
609
  wp_update_term( $author_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
610
  }
611
  WP_CLI::success( 'All done! Grab a cold one (Affogatto)' );
@@ -624,7 +626,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
624
  WP_CLI::line( 'Now updating ' . count( $author_terms ) . ' terms' );
625
  foreach ( $author_terms as $author_term ) {
626
  $old_count = $author_term->count;
627
- $coauthor = $coauthors_plus->get_coauthor_by( 'user_nicename', $author_term->slug );
628
  $coauthors_plus->update_author_term( $coauthor );
629
  $coauthors_plus->update_author_term_post_count( $author_term );
630
  wp_cache_delete( $author_term->term_id, $coauthors_plus->coauthor_taxonomy );
@@ -725,7 +727,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
725
  public function create_guest_authors_from_wxr( $args, $assoc_args ) {
726
  global $coauthors_plus;
727
 
728
- $defaults = array(
729
  'file' => '',
730
  );
731
  $this->args = wp_parse_args( $assoc_args, $defaults );
@@ -735,10 +737,10 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
735
  }
736
 
737
  if ( ! class_exists( 'WXR_Parser' ) ) {
738
- require_once( WP_CONTENT_DIR . '/plugins/wordpress-importer/parsers.php' );
739
  }
740
 
741
- $parser = new WXR_Parser();
742
  $import_data = $parser->parse( $this->args['file'] );
743
 
744
  if ( is_wp_error( $import_data ) ) {
@@ -753,11 +755,11 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
753
 
754
  $guest_author_data = array(
755
  'display_name' => $author['author_display_name'],
756
- 'user_login' => $author['author_login'],
757
- 'user_email' => $author['author_email'],
758
- 'first_name' => $author['author_first_name'],
759
- 'last_name' => $author['author_last_name'],
760
- 'ID' => $author['author_id'],
761
  );
762
 
763
  $guest_author_id = $this->create_guest_author( $guest_author_data );
@@ -775,7 +777,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
775
  public function create_guest_authors_from_csv( $args, $assoc_args ) {
776
  global $coauthors_plus;
777
 
778
- $defaults = array(
779
  'file' => '',
780
  );
781
  $this->args = wp_parse_args( $assoc_args, $defaults );
@@ -798,7 +800,7 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
798
  $field_keys = array_map( 'trim', $data );
799
  // TODO: bail if required fields not found
800
  } else {
801
- $row_data = array_map( 'trim', $data );
802
  $author_data = array();
803
  foreach ( (array) $row_data as $col_num => $val ) {
804
  // Don't use the value of the field key isn't set
@@ -821,24 +823,24 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
821
 
822
  $guest_author_data = array(
823
  'display_name' => sanitize_text_field( $author['display_name'] ),
824
- 'user_login' => sanitize_user( $author['user_login'] ),
825
- 'user_email' => sanitize_email( $author['user_email'] ),
826
- 'website' => esc_url_raw( $author['website'] ),
827
- 'description' => wp_filter_post_kses( $author['description'] ),
828
- 'avatar' => absint( $author['avatar'] ),
829
  );
830
 
831
  $display_name_space_pos = strpos( $author['display_name'], ' ' );
832
 
833
  if ( false !== $display_name_space_pos && empty( $author['first_name'] ) && empty( $author['last_name'] ) ) {
834
  $first_name = substr( $author['display_name'], 0, $display_name_space_pos );
835
- $last_name = substr( $author['display_name'], ( $display_name_space_pos + 1 ) );
836
 
837
  $guest_author_data['first_name'] = sanitize_text_field( $first_name );
838
- $guest_author_data['last_name'] = sanitize_text_field( $last_name );
839
  } elseif ( ! empty( $author['first_name'] ) && ! empty( $author['last_name'] ) ) {
840
  $guest_author_data['first_name'] = sanitize_text_field( $author['first_name'] );
841
- $guest_author_data['last_name'] = sanitize_text_field( $author['last_name'] );
842
  }
843
 
844
  $guest_author_id = $this->create_guest_author( $guest_author_data );
@@ -858,16 +860,18 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
858
  if ( ! $guest_author ) {
859
  WP_CLI::line( '-- Not found; creating profile.' );
860
 
861
- $guest_author_id = $coauthors_plus->guest_authors->create( array(
862
- 'display_name' => $author['display_name'],
863
- 'user_login' => $author['user_login'],
864
- 'user_email' => $author['user_email'],
865
- 'first_name' => $author['first_name'],
866
- 'last_name' => $author['last_name'],
867
- 'website' => $author['website'],
868
- 'description' => $author['description'],
869
- 'avatar' => $author['avatar'],
870
- ) );
 
 
871
 
872
  if ( $guest_author_id ) {
873
  WP_CLI::line( sprintf( '-- Created as guest author #%s', $guest_author_id ) );
@@ -897,10 +901,10 @@ class CoAuthorsPlus_Command extends WP_CLI_Command {
897
  return;
898
  }
899
 
900
- $wp_object_cache->group_ops = array();
901
- $wp_object_cache->stats = array();
902
  $wp_object_cache->memcache_debug = array();
903
- $wp_object_cache->cache = array();
904
 
905
  if ( is_callable( $wp_object_cache, '__remoteset' ) ) {
906
  $wp_object_cache->__remoteset(); // important
22
 
23
  $defaults = array(
24
  // There are no arguments at this time
25
+ );
26
  $this->args = wp_parse_args( $assoc_args, $defaults );
27
 
28
+ $users = get_users();
29
+ $created = 0;
30
+ $skipped = 0;
31
+ $progress = \WP_CLI\Utils\make_progress_bar( 'Processing guest authors...', count( $users ) );
32
  foreach ( $users as $user ) {
33
 
34
  $result = $coauthors_plus->guest_authors->create_guest_author_from_user_id( $user->ID );
54
  global $coauthors_plus, $wp_post_types;
55
 
56
  // Cache these to prevent repeated lookups
57
+ $authors = array();
58
  $author_terms = array();
59
 
60
  $args = array(
61
+ 'order' => 'ASC',
62
+ 'orderby' => 'ID',
63
+ 'post_type' => $coauthors_plus->supported_post_types,
64
+ 'posts_per_page' => 100,
65
+ 'paged' => 1,
66
+ 'update_meta_cache' => false,
67
+ );
68
 
69
+ $posts = new WP_Query( $args );
70
+ $affected = 0;
71
+ $count = 0;
72
  $total_posts = $posts->found_posts;
73
  WP_CLI::line( "Now inspecting or updating {$posts->found_posts} total posts." );
74
  while ( $posts->post_count ) {
87
  continue;
88
  }
89
 
90
+ $author = ( ! empty( $authors[ $single_post->post_author ] ) ) ? $authors[ $single_post->post_author ] : get_user_by( 'id', $single_post->post_author );
91
  $authors[ $single_post->post_author ] = $author;
92
 
93
+ $author_term = ( ! empty( $author_terms[ $single_post->post_author ] ) ) ? $author_terms[ $single_post->post_author ] : $coauthors_plus->update_author_term( $author );
94
  $author_terms[ $single_post->post_author ] = $author_term;
95
 
96
  wp_set_post_terms( $single_post->ID, array( $author_term->slug ), $coauthors_plus->coauthor_taxonomy );
126
  public function assign_coauthors( $args, $assoc_args ) {
127
  global $coauthors_plus;
128
 
129
+ $defaults = array(
130
+ 'meta_key' => '_original_import_author',
131
+ 'post_type' => 'post',
132
+ 'order' => 'ASC',
133
+ 'orderby' => 'ID',
134
+ 'posts_per_page' => 100,
135
+ 'paged' => 1,
136
+ 'append_coauthors' => false,
137
+ );
138
  $this->args = wp_parse_args( $assoc_args, $defaults );
139
 
140
  // For global use and not a part of WP_Query
141
  $append_coauthors = $this->args['append_coauthors'];
142
  unset( $this->args['append_coauthors'] );
143
 
144
+ $posts_total = 0;
145
  $posts_already_associated = 0;
146
+ $posts_missing_coauthor = 0;
147
+ $posts_associated = 0;
148
+ $missing_coauthors = array();
149
 
150
  $posts = new WP_Query( $this->args );
151
  while ( $posts->post_count ) {
154
  $posts_total++;
155
 
156
  // See if the value in the post meta field is the same as any of the existing coauthors
157
+ $original_author = get_post_meta( $single_post->ID, $this->args['meta_key'], true );
158
  $existing_coauthors = get_coauthors( $single_post->ID );
159
  $already_associated = false;
160
  foreach ( $existing_coauthors as $existing_coauthor ) {
215
  public function assign_user_to_coauthor( $args, $assoc_args ) {
216
  global $coauthors_plus, $wpdb;
217
 
218
+ $defaults = array(
219
+ 'user_login' => '',
220
+ 'coauthor' => '',
221
+ );
222
  $assoc_args = wp_parse_args( $assoc_args, $defaults );
223
 
224
+ $user = get_user_by( 'login', $assoc_args['user_login'] );
225
  $coauthor = $coauthors_plus->get_coauthor_by( 'login', $assoc_args['coauthor'] );
226
 
227
  if ( ! $user ) {
233
  }
234
 
235
  $post_types = implode( "','", $coauthors_plus->supported_post_types );
236
+ $posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author=%d AND post_type IN (%s)", $user->ID, $post_types ) );
237
+ $affected = 0;
238
  foreach ( $posts as $post_id ) {
239
  $coauthors = cap_get_coauthor_terms_for_post( $post_id );
240
  if ( ! empty( $coauthors ) ) {
241
+ WP_CLI::line(
242
+ sprintf(
243
+ __( 'Skipping - Post #%1$d already has co-authors assigned: %2$s', 'co-authors-plus' ),
244
+ $post_id,
245
+ implode( ', ', wp_list_pluck( $coauthors, 'slug' ) )
246
+ )
247
+ );
248
  continue;
249
  }
250
 
251
  $coauthors_plus->add_coauthors( $post_id, array( $coauthor->user_login ) );
252
+ WP_CLI::line( sprintf( __( "Updating - Adding %1\$s's byline to post #%2\$d", 'co-authors-plus' ), $coauthor->user_login, $post_id ) );
253
  $affected++;
254
  if ( $affected && 0 === $affected % 100 ) {
255
  sleep( 2 );
276
  public function reassign_terms( $args, $assoc_args ) {
277
  global $coauthors_plus;
278
 
279
+ $defaults = array(
280
+ 'author_mapping' => null,
281
+ 'old_term' => null,
282
+ 'new_term' => null,
283
+ );
284
  $this->args = wp_parse_args( $assoc_args, $defaults );
285
 
286
  $author_mapping = $this->args['author_mapping'];
287
+ $old_term = $this->args['old_term'];
288
+ $new_term = $this->args['new_term'];
289
 
290
  // Get the reassignment data
291
  if ( $author_mapping && file_exists( $author_mapping ) ) {
292
+ require_once $author_mapping;
293
  $authors_to_migrate = $cli_user_map;
294
+ } elseif ( $author_mapping ) {
295
  WP_CLI::error( "author_mapping doesn't exist: " . $author_mapping );
296
  exit;
297
  }
299
  // Alternate reassigment approach
300
  if ( $old_term && $new_term ) {
301
  $authors_to_migrate = array(
302
+ $old_term => $new_term,
303
+ );
304
  }
305
 
306
  // For each author to migrate, check whether the term exists,
307
  // whether the target term exists, and only do the migration if both are met
308
  $results = (object) array(
309
+ 'old_term_missing' => 0,
310
+ 'new_term_exists' => 0,
311
+ 'success' => 0,
312
+ );
313
  foreach ( $authors_to_migrate as $old_user => $new_user ) {
314
 
315
  if ( is_numeric( $new_user ) ) {
331
  if ( is_object( $new_term ) ) {
332
  WP_CLI::line( "Success: There's already a '{$new_user}' term for '{$old_user}'. Reassigning {$old_term->count} posts and then deleting the term" );
333
  $args = array(
334
+ 'default' => $new_term->term_id,
335
+ 'force_default' => true,
336
+ );
337
  wp_delete_term( $old_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
338
  $results->new_term_exists++;
339
  } else {
340
  $args = array(
341
+ 'slug' => $new_user,
342
+ 'name' => $new_user,
343
+ );
344
  wp_update_term( $old_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
345
  WP_CLI::line( "Success: Converted '{$old_user}' term to '{$new_user}'" );
346
  $results->success++;
368
  public function rename_coauthor( $args, $assoc_args ) {
369
  global $coauthors_plus, $wpdb;
370
 
371
+ $defaults = array(
372
+ 'from' => null,
373
+ 'to' => null,
374
+ );
375
  $assoc_args = array_merge( $defaults, $assoc_args );
376
 
377
+ $to_userlogin = $assoc_args['to'];
378
  $to_userlogin_prefixed = 'cap-' . $to_userlogin;
379
 
380
  $orig_coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $assoc_args['from'] );
394
 
395
  WP_CLI::line( "Renaming {$orig_term->name} to {$to_userlogin}" );
396
  $rename_args = array(
397
+ 'name' => $to_userlogin,
398
+ 'slug' => $to_userlogin_prefixed,
399
+ );
400
  wp_update_term( $orig_term->term_id, $coauthors_plus->coauthor_taxonomy, $rename_args );
401
 
402
  if ( 'guest-author' == $orig_coauthor->type ) {
423
  $defaults = array(
424
  'from' => null,
425
  'to' => null,
426
+ 'post_type' => 'post',
427
+ 'dry' => false,
428
  );
429
 
430
  $assoc_args = array_merge( $defaults, $assoc_args );
431
 
432
+ $dry = $assoc_args['dry'];
433
 
434
+ $from_userlogin = $assoc_args['from'];
435
+ $to_userlogin = $assoc_args['to'];
436
 
437
+ $from_userlogin_prefixed = 'cap-' . $from_userlogin;
438
+ $to_userlogin_prefixed = 'cap-' . $to_userlogin;
439
 
440
  $orig_coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $from_userlogin );
441
 
456
  WP_CLI::line( "Swapping authorship from {$from_userlogin} to {$to_userlogin}" );
457
 
458
  $query_args = array(
459
+ 'post_type' => $assoc_args['post_type'],
460
+ 'order' => 'ASC',
461
+ 'orderby' => 'ID',
462
+ 'posts_per_page' => 100,
463
+ 'paged' => 1,
464
+ 'tax_query' => array(
465
  array(
466
+ 'taxonomy' => $coauthors_plus->coauthor_taxonomy,
467
+ 'field' => 'slug',
468
+ 'terms' => array( $from_userlogin_prefixed ),
469
  ),
470
  ),
471
  );
536
  public function list_posts_without_terms( $args, $assoc_args ) {
537
  global $coauthors_plus;
538
 
539
+ $defaults = array(
540
+ 'post_type' => 'post',
541
+ 'order' => 'ASC',
542
+ 'orderby' => 'ID',
543
+ 'year' => '',
544
+ 'posts_per_page' => 300,
545
+ 'paged' => 1,
546
+ 'no_found_rows' => true,
547
+ 'update_meta_cache' => false,
548
+ );
549
  $this->args = wp_parse_args( $assoc_args, $defaults );
550
 
551
  $posts = new WP_Query( $this->args );
556
  $terms = cap_get_coauthor_terms_for_post( $single_post->ID );
557
  if ( empty( $terms ) ) {
558
  $saved = array(
559
+ $single_post->ID,
560
+ addslashes( $single_post->post_title ),
561
+ get_permalink( $single_post->ID ),
562
+ $single_post->post_date,
563
+ );
564
  WP_CLI::line( '"' . implode( '","', $saved ) . '"' );
565
  }
566
  }
597
  if ( $prefixed_term = get_term_by( 'slug', 'cap-' . $author_term->slug, $coauthors_plus->coauthor_taxonomy ) ) {
598
  WP_CLI::line( "Term {$author_term->slug} ({$author_term->term_id}) has a new term too: $prefixed_term->slug ($prefixed_term->term_id). Merging" );
599
  $args = array(
600
+ 'default' => $author_term->term_id,
601
  'force_default' => true,
602
  );
603
  wp_delete_term( $prefixed_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
606
  // Term isn't prefixed, doesn't have a sibling, and should be updated
607
  WP_CLI::line( "Term {$author_term->slug} ({$author_term->term_id}) isn't prefixed, adding one" );
608
  $args = array(
609
+ 'slug' => 'cap-' . $author_term->slug,
610
+ );
611
  wp_update_term( $author_term->term_id, $coauthors_plus->coauthor_taxonomy, $args );
612
  }
613
  WP_CLI::success( 'All done! Grab a cold one (Affogatto)' );
626
  WP_CLI::line( 'Now updating ' . count( $author_terms ) . ' terms' );
627
  foreach ( $author_terms as $author_term ) {
628
  $old_count = $author_term->count;
629
+ $coauthor = $coauthors_plus->get_coauthor_by( 'user_nicename', $author_term->slug );
630
  $coauthors_plus->update_author_term( $coauthor );
631
  $coauthors_plus->update_author_term_post_count( $author_term );
632
  wp_cache_delete( $author_term->term_id, $coauthors_plus->coauthor_taxonomy );
727
  public function create_guest_authors_from_wxr( $args, $assoc_args ) {
728
  global $coauthors_plus;
729
 
730
+ $defaults = array(
731
  'file' => '',
732
  );
733
  $this->args = wp_parse_args( $assoc_args, $defaults );
737
  }
738
 
739
  if ( ! class_exists( 'WXR_Parser' ) ) {
740
+ require_once WP_CONTENT_DIR . '/plugins/wordpress-importer/parsers.php';
741
  }
742
 
743
+ $parser = new WXR_Parser();
744
  $import_data = $parser->parse( $this->args['file'] );
745
 
746
  if ( is_wp_error( $import_data ) ) {
755
 
756
  $guest_author_data = array(
757
  'display_name' => $author['author_display_name'],
758
+ 'user_login' => $author['author_login'],
759
+ 'user_email' => $author['author_email'],
760
+ 'first_name' => $author['author_first_name'],
761
+ 'last_name' => $author['author_last_name'],
762
+ 'ID' => $author['author_id'],
763
  );
764
 
765
  $guest_author_id = $this->create_guest_author( $guest_author_data );
777
  public function create_guest_authors_from_csv( $args, $assoc_args ) {
778
  global $coauthors_plus;
779
 
780
+ $defaults = array(
781
  'file' => '',
782
  );
783
  $this->args = wp_parse_args( $assoc_args, $defaults );
800
  $field_keys = array_map( 'trim', $data );
801
  // TODO: bail if required fields not found
802
  } else {
803
+ $row_data = array_map( 'trim', $data );
804
  $author_data = array();
805
  foreach ( (array) $row_data as $col_num => $val ) {
806
  // Don't use the value of the field key isn't set
823
 
824
  $guest_author_data = array(
825
  'display_name' => sanitize_text_field( $author['display_name'] ),
826
+ 'user_login' => sanitize_user( $author['user_login'] ),
827
+ 'user_email' => sanitize_email( $author['user_email'] ),
828
+ 'website' => esc_url_raw( $author['website'] ),
829
+ 'description' => wp_filter_post_kses( $author['description'] ),
830
+ 'avatar' => absint( $author['avatar'] ),
831
  );
832
 
833
  $display_name_space_pos = strpos( $author['display_name'], ' ' );
834
 
835
  if ( false !== $display_name_space_pos && empty( $author['first_name'] ) && empty( $author['last_name'] ) ) {
836
  $first_name = substr( $author['display_name'], 0, $display_name_space_pos );
837
+ $last_name = substr( $author['display_name'], ( $display_name_space_pos + 1 ) );
838
 
839
  $guest_author_data['first_name'] = sanitize_text_field( $first_name );
840
+ $guest_author_data['last_name'] = sanitize_text_field( $last_name );
841
  } elseif ( ! empty( $author['first_name'] ) && ! empty( $author['last_name'] ) ) {
842
  $guest_author_data['first_name'] = sanitize_text_field( $author['first_name'] );
843
+ $guest_author_data['last_name'] = sanitize_text_field( $author['last_name'] );
844
  }
845
 
846
  $guest_author_id = $this->create_guest_author( $guest_author_data );
860
  if ( ! $guest_author ) {
861
  WP_CLI::line( '-- Not found; creating profile.' );
862
 
863
+ $guest_author_id = $coauthors_plus->guest_authors->create(
864
+ array(
865
+ 'display_name' => $author['display_name'],
866
+ 'user_login' => $author['user_login'],
867
+ 'user_email' => $author['user_email'],
868
+ 'first_name' => $author['first_name'],
869
+ 'last_name' => $author['last_name'],
870
+ 'website' => $author['website'],
871
+ 'description' => $author['description'],
872
+ 'avatar' => $author['avatar'],
873
+ )
874
+ );
875
 
876
  if ( $guest_author_id ) {
877
  WP_CLI::line( sprintf( '-- Created as guest author #%s', $guest_author_id ) );
901
  return;
902
  }
903
 
904
+ $wp_object_cache->group_ops = array();
905
+ $wp_object_cache->stats = array();
906
  $wp_object_cache->memcache_debug = array();
907
+ $wp_object_cache->cache = array();
908
 
909
  if ( is_callable( $wp_object_cache, '__remoteset' ) ) {
910
  $wp_object_cache->__remoteset(); // important
php/integrations/amp.php CHANGED
@@ -13,7 +13,7 @@ function cap_update_amp_json_metadata( $metadata, $post ) {
13
  foreach ( $authors as $author ) {
14
  $authors_json[] = array(
15
  '@type' => 'Person',
16
- 'name' => $author->display_name,
17
  );
18
  }
19
  $metadata['author'] = $authors_json;
13
  foreach ( $authors as $author ) {
14
  $authors_json[] = array(
15
  '@type' => 'Person',
16
+ 'name' => $author->display_name,
17
  );
18
  }
19
  $metadata['author'] = $authors_json;
phpunit.xml CHANGED
@@ -10,7 +10,7 @@
10
  <const name="WP_TESTS_MULTISITE" value="1" />
11
  </php>
12
  <testsuites>
13
- <testsuite>
14
  <directory prefix="test-" suffix=".php">./tests/</directory>
15
  </testsuite>
16
  </testsuites>
10
  <const name="WP_TESTS_MULTISITE" value="1" />
11
  </php>
12
  <testsuites>
13
+ <testsuite name="WP_Tests">
14
  <directory prefix="test-" suffix=".php">./tests/</directory>
15
  </testsuite>
16
  </testsuites>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: batmoo, danielbachhuber, automattic
3
  Tags: authors, users, multiple authors, coauthors, multi-author, publishing
4
  Tested up to: 5.7
5
  Requires at least: 4.1
6
- Stable tag: 3.4.5
7
 
8
  Assign multiple bylines to posts, pages, and custom post types via a search-as-you-type input box
9
 
@@ -46,309 +46,6 @@ Yep! There's a template tag called `coauthors_wp_list_authors()` that accepts ma
46
  Yep! Guest authors can be disabled entirely through an apt filter. Having the following line load on `init` will do the trick:
47
  `add_filter( 'coauthors_guest_authors_enabled', '__return_false' )`
48
 
49
- == Upgrade Notice ==
50
-
51
- = 3.1 =
52
- Manage co-authors from quick edit, Jetpack Open Graph support, bug fixes.
53
-
54
- = 3.0.7 =
55
- Support for symlink installations, updated French translation, bug fixes.
56
-
57
- = 3.0.4 =
58
- Bug fixes and the ability to automatically add co-authors to your feeds.
59
-
60
- = 3.0.1 =
61
- Bug fixes and minor enhancements
62
-
63
- == Changelog ==
64
-
65
- =3.4.5=
66
- * Fixed bug where guest authors with spaces in names were not showing when queried in AJAX suggest box.
67
-
68
- = 3.4.4 =
69
- * Fixed bug where author with slug beginning with "cap" does not appear in bylines AJAX suggest box when queried
70
- * Travis for Xenial build no longer fails
71
- * Unit tests no longer fail
72
- * Fixed REST permissions bug where co-author cannot view post assigned to them in Gutenberg
73
-
74
- = 3.4.3 =
75
- * Added author support to CPT instructions in readme FAQ
76
- * Added object check for user in `coauthors_set_post_author_field()`
77
- * Fix inefficient user query in avatar url hook
78
- * Fix operand typo in `get_guest_author_thumbnail()` for adding custom classes
79
- * Remove hardcoded default avatar and use default option
80
-
81
- = 3.4.2 =
82
- * Fix incorrect user avatar being displayed from featured post image
83
- * Add check for `filter_get_avatar_url` to ensure valid second parameter
84
- * `add_coauthors()` accepts ID parameter now and ensures valid term slug used
85
- * `filter_count_user_posts` checks that user ID returns valid user object
86
- * Added post count instructions in readme FAQ for CPTs
87
-
88
- = 3.4.1 =
89
- * Fix an issue that may arise in bulk edit
90
-
91
- = 3.4 =
92
- * New filter get_coauthors for modifying coauthor data returned in get_coauthors()
93
- * New filter coauthors_guest_authors_exported_extra_data to allow guest author to export data as regular author
94
- * New filter get_avatar_url() to show avatar in JS selection
95
- * New parameter in coauthors_wp_list_authors() to only query authors with posts
96
- * Add internationalization support to title and name in author archives
97
- * Add safelist to skip irrelevant capabilities during permission checks
98
- * Add helper function get_guest_author_post_count()
99
- * Add parameter for outputting HTML classes in coauthors_get_avatar() template tag
100
- * Add --append_coauthors flag to synopsis of CLI assign-coauthors
101
- * Adjust CLI command create-guest-authors-from-csv to import website, avatar and description
102
- * Post type of "any" can be used in filters
103
- * Remove unnecessary is_array() check
104
- * Remove unnecessary action_pre_user_query()
105
- * Use correct args in search_authors()
106
- * Have filter_author_archive_title() run on author archives only
107
- * Improve tests coverage
108
- * Change posts_selection to action from filter
109
- * Fix number of args expected for get_the_archive_title callback
110
- * Fix spelling, update FAQ for disabling guest authors and credits in readme
111
- * Output coauthors_links_single() template tag correctly when guest author has no website
112
- * Number by "Mine" link shows correct listing of posts
113
- * Linked guest authors show accurate post counts
114
- * Can no longer add co-author more than once
115
- * No more overwriting posts with current user in `add_coauthors()`
116
- * Accurate post count for user when using different login
117
- * No more double post count for users with linked accounts
118
- * Fix SQL error
119
- * Fix "Mine" link href for Pages
120
- * Can delete users when guest authors functionality disabled
121
- * Fix incompatibility issue with Yoast of missing posts in author pages
122
- * Resolve undefined index warnings on author archives
123
- * Resolve warnings when current user has no term assigned
124
-
125
- = 3.3.1 ("Gutentag") =
126
- * 5.0 Compat: Hide core author inputs when using the Block Editor to limit confusion (h/t jonathanstegall).
127
-
128
- = 3.3.0 ("Rebecca") =
129
- * Fix private post viewing on front-end
130
- * Reduce amount of sleep
131
- * Author search UX issues
132
- * Remove associated guest user when mapped user id deleted.
133
- * Removed double left join on posts_join_filter
134
- * Fixed WP CLI create-terms-for-posts if no co-authors found
135
- * Pages archive now displays coauthors and quick edit works
136
- * Terminology updated throughout
137
- * Replace hardcoded 'author' with $this->$coauthor_taxonomy
138
- * Move parenthesis to fix esc_html and sprintf
139
- * Added progress to create-guest-authors so users have an idea of how long it will take
140
- * Deleting guest authors is less confusing
141
- * Guest author's featured image is avatar now
142
- * Removed extra image sizing
143
- * Remove duplicated byline
144
- * coauthors_wp_list_authors() has option to list only guest authors now
145
- * remove duplicates from linked accounts on coauthors_wp_list_authors()
146
- * Accurate Guest Author post count on linked accounts
147
- * New README.md
148
- * Filter author archive
149
- * Fix coauthors_links_single()
150
- * Added guest author hooks for create/delete
151
- * Fixes logic for DOING_AUTOSAVE check
152
- * user_login spaces problem when using add_coauthors
153
- * Adding details of filter for slow performance
154
- * Remove redundant test for 404 on Author Archive
155
- * Guest Author Counts are more accurate
156
- * Set $coauthors_loading
157
- * Fix the issue where guest authors with non-ASCII characters can't be used as co-authors
158
- * Fix the issue where incompatibility when `coauthors_auto_apply_template_tags` set to true
159
- * Unit tests/Fix warnings for template tags
160
- * Review and improve test coverage
161
- * Update class-wp-cli.php
162
- * Update .travis.yml file for PHPUnit tests
163
- * Changes to resolve issue #332 about missing coauthor meta
164
-
165
- = 3.2.2 =
166
- * Fix broken author ordering in 4.7+ (props mslinnea)
167
- * Fix no moderation e-mail bug (props RobjS)
168
- * Cached functions in CLI commands (props jasonbahl)
169
- * Fix missing echos (props trepmal)
170
- * Add `coauthors_guest_author_query_args` filter (props trepmal)
171
-
172
- = 3.2.1 (May 16, 2016) =
173
- * Hotfix for broken Guest Author bio metabox (props JS Morisset)
174
-
175
- = 3.2 (May 12, 2016) =
176
- Various minor bug and security fixes
177
-
178
- = 3.1.2 (Aug. 31, 2015) =
179
- * Minor bug fixes and coding standards changes.
180
- * The author's display name is now filtered through the_author in coauthors_posts_links_single()
181
- * New Russian and Ukrainian translations, courtesy of [Jurko Chervony](http://skinik.name/).
182
-
183
- = 3.1.1 (Mar. 20, 2014) =
184
- * Bug fix: Co-authors selection UI should appear when creating a new post too.
185
-
186
- = 3.1 (Mar. 17, 2014) =
187
- * Manage co-authors from Quick Edit. Props [mpatek](https://github.com/mpatek).
188
- * Updated Spanish translation, courtesy of [sergiomajluf](https://github.com/sergiomajluf).
189
- * Now matches core behavior when displaying author archive on multisite: user of the blog, or previously published author on the blog.
190
- * Breaking change: "Create Profile" link is no longer shown by default on the Manage Users screen. Instead, it can be enabled with the `coauthors_show_create_profile_user_link` filter.
191
- * Guest authors work properly with Jetpack Open Graph tags. Props [hibernation](https://github.com/hibernation).
192
- * Guest author profile editor now supports a few different fields. Props [alpha1](https://github.com/alpha1).
193
- * New `coauthors_count_published_post_types` filter for specifying the post type(s) used when calculating the user's number of published posts.
194
- * Bug fix: Ensure `post_author` is set to one of the co-authors assigned to a post.
195
- * Bug fix: Filter author feed link for guest authors on the author page. Props [hibernation](https://github.com/hibernation).
196
- * Packages a composer.json file for those using Composer.
197
- * Beginnings of unit test coverage for core features. Increased minimum required WordPress version to 3.7 because WordPress.org unit testing framework doesn't work reliabilty below that.
198
-
199
- = 3.0.7 (Jan. 27, 2014) =
200
- * Better support for installing Co-Authors Plus as a symlinked directory. [Follow these instructions](http://kaspars.net/blog/wordpress/plugins-via-symlinks) to filter `plugins_url`.
201
- * Links to authors' posts pages to comply to hCard microformat, which Google depends on.
202
- * New `coauthors_emails()` template tag to list email addresses of the co-authors. Props [benlk](https://github.com/benlk).
203
- * Bug fix: Remove extraneous space between last two co-authors output. Props [johnciacia](https://github.com/johnciacia).
204
- * Updated French translation, courtesy of Jojaba (via email).
205
-
206
- = 3.0.6 (Dec. 9, 2013) =
207
- * New Swedish translation, courtesy of [alundstroem](https://github.com/alundstroem)
208
- * Updated German translation, courtesy of [krafit](https://github.com/krafit).
209
- * New Dutch translation, courtesy of [kardotim](https://github.com/kardotim)
210
- * New filter for specifying the default author assigned to a post. Props [tannerm](https://github.com/tannerm)
211
- * Bug fix: When filtering a user's published post count, use the value of their guest author profile if one is mapped.
212
- * Added support for checkboxes in Guest Author profiles
213
- * Fix Strict warnings from CPT's that don't define all capabilities
214
- * New swap-coauthors CLI command for replacing one co-author with another
215
-
216
- = 3.0.5 (Feb. 18, 2013) =
217
- * New filter 'coauthors_search_authors_get_terms_args' allows you to increase the number of matches returned with AJAX co-author selection
218
- * Bug fix: If there isn't an author term yet for a co-author, avoid an erronous join that caused duplicate posts to appear.
219
-
220
- = 3.0.4 (Jan. 6, 2013) =
221
- * Support for automatically adding co-authors to your feeds. Props [cfg](https://github.com/cfg).
222
- * Bug fix: No Co-Authors Plus on attachments. For now.
223
- * Bug fix: Better support for co-authors with non-standard user_nicenames. Props [STRML](https://github.com/STRML).
224
-
225
- = 3.0.3 (Dec. 3, 2012) =
226
- * Bug fix: The default order for the 'author' taxonomy should be 'term_order', in order for the author positions to stick. Props [lgedeon](https://github.com/lgedeon)
227
-
228
- = 3.0.2 (Nov. 23, 2012) =
229
- * Bug fix: Fall back to non-pretty permalinks when the author permastruct is empty, so that coauthors_posts_links() doesn't link to the homepage
230
-
231
- = 3.0.1 (Nov. 21, 2012) =
232
- * Add your own custom columns to the guest authors table using filters. Props [cfg](https://github.com/cfg)
233
- * A new wp-cli subcommand for renaming co-authors and another for removing author terms mistakenly assigned to revisions
234
- * Bug fix: Using a featured image for a guest author avatar didn't work. Now it does.
235
- * Bug fix: Don't assign author terms to revisions to avoid unnecessary database bloat
236
- * Bug fix: Make the coauthors_wp_list_authors() template tag work again
237
- * Bug fix: Improve capability filtering by properly handling super admin access and situations where user_id = 0
238
- * Minor UI enhancements for guest authors
239
-
240
- = 3.0 (Nov. 12, 2012) =
241
- * Create guest author profiles for bylines you'd like to assign without creating WordPress user accounts. Guest authors can have all of the same fields as normal users including display name, biography, and avatars.
242
- * Support for non-Latin characters in usernames and guest author names
243
- * wp-cli subcommands for creating, assigning, and reassigning co-authors
244
- * For themes using core template tags like the_author() or the_author_posts_link(), you enable Co-Authors Plus support with a simple filter
245
- * New author terms are now prefixed with 'cap-' to avoid collisions with global scope
246
- * Bug fix: Apply query filters to only post_types registered with the taxonomy. Props [Tom Ransom](https://github.com/1bigidea)
247
- * Filter coauthors_posts_link_single() with 'coauthors_posts_link'. Also adds rel="author". Props [Amit Sannad](https://github.com/asannad) and [Gabriel Koen](https://github.com/mintindeed)
248
- * Filter for the context and priorities of the Co-Authors meta boxes. Props [Tomáš Kapler](https://github.com/tkapler)
249
- * Renamed the post meta box for selecting authors so it applies to many post types. Props [John Blackbourn](https://github.com/johnbillion)
250
-
251
- = 2.6.4 (May 7, 2012) =
252
- * Bug fix: Properly filter the user query so users can AJAX search against the display name field again
253
- * If https is used for the admin, also use the secure Gravatar URL. Props [rmcfrazier](https://github.com/rmcfrazier)
254
-
255
- = 2.6.3 (Apr. 30, 2012) =
256
- * AJAX user search is back to searching against user login, display name, email address and user ID. The method introduced in v2.6.2 didn't scale well
257
- * French translation courtesy of Sylvain Bérubé
258
- * Spanish translation courtesy of Alejandro Arcos
259
- * Bug fix: Resolved incorrect caps check against user editing an already published post. [See forum thread](http://wordpress.org/support/topic/multiple-authors-cant-edit-pages?replies=17#post-2741243)
260
-
261
- = 2.6.2 (Mar. 6, 2012) =
262
- * AJAX user search matches against first name, last name, and nickname fields too, in addition to display name, user login, and email address
263
- * Comment moderation and approved notifications are properly sent to all co-authors with the correct caps
264
- * Filter required capability for user to be returned in an AJAX search with 'coauthors_edit_author_cap'
265
- * Filter out administrators and other non-authors from AJAX search with 'coauthors_edit_ignored_authors'
266
- * Automatically adds co-authors to Edit Flow's story budget and calendar views
267
- * Bug fix: Don't set post_author value to current user when quick editing a post. This doesn't appear in the UI anywhere, but adds the post to the current user's list of posts
268
- * Bug fix: Properly cc other co-authors on new comment email notifications
269
- * Bug fix: If a user has already been added as an author to a post, don't show them in the AJAX search again
270
- * Bug fix: Allow output constants to be defined in a theme's functions.php file and include filters you can use instead
271
-
272
- = 2.6.1 (Dec. 30, 2011) =
273
- * Fix mangled usernames because of sanitize_key http://wordpress.org/support/topic/plugin-co-authors-plus-26-not-working-with-wp-33
274
-
275
- = 2.6 (Dec. 22, 2011) =
276
- * Sortable authors: Drag and drop the order of the authors as you'd like them to appear ([props kingkool68](http://profiles.wordpress.org/users/kingkool68/))
277
- * Search for authors by display name (instead of nicename which was essentially the same as user_login)
278
- * Option to remove the first author when there are two or more so it's less confusing
279
- * Bumped requirements to WordPress 3.1
280
- * Bug fix: Update the published post count for each user more reliably
281
-
282
- = 2.5.3 (Aug. 14, 2011) =
283
- * Bug fix: Removed extra comma when only two authors were listed. If you used the COAUTHORS_DEFAULT_BETWEEN_LAST constant, double-check what you have
284
-
285
- = 2.5.2 (Apr. 23, 2011) =
286
- * Bug: Couldn't query terms and authors at the same time (props nbaxley)
287
- * Bug: Authors with empty fields (e.g. first name) were displaying blank in some cases
288
- * Bug: authors with spaces in usernames not getting saved (props MLmsw, Ruben S. and others!)
289
- * Bug: revisions getting wrong user attached (props cliquenoir!)
290
-
291
- = 2.5.1 (Mar. 26, 2011) =
292
- * Fix with author post count (throwing errors)
293
-
294
- = 2.5 (Mar. 26, 2011) =
295
- * Custom Post Type Support
296
- * Compatibility with WP 3.0 and 3.1
297
- * Gravatars
298
- * Lots and lots and lots of bug fixes
299
- * Thanks to everyone who submitted bugs, fixes, and suggestions! And for your patience!
300
-
301
- = 2.1.1 (Oct. 16, 2009) =
302
- * Fix for coauthors not being added if their username is different from display name
303
- * Fixes to readme.txt (fixes for textual and punctuation errors, language clarification, minor formatting changes) courtesy of [Waldo Jaquith](http://www.vqronline.org)
304
-
305
- = 2.1 (Oct. 11, 2009) =
306
- * Fixed issues related to localization. Thanks to Jan Zombik <zombik@students.uni-mainz.de> for the fixes.
307
- * Added set_time_limit to update function to get around timeout issues when upgrading plugin
308
-
309
- = 2.0 (Oct. 11, 2009) =
310
- * Plugin mostly rewritten to make use of taxonomy instead of post_meta
311
- * Can now see all authors of a post under the author column from Edit Posts page
312
- * All authors of a post are now notified on a new comment
313
- * Various javascript enhancements
314
- * New option to allow subscribers to be added as authors
315
- * All Authors can edit they posts of which they are coauthors
316
- * FIX: Issues with wp_coauthors_list function
317
- * FIX: Issues with coauthored posts not showing up on author archives
318
-
319
- = 1.2.0 (Jun. 16, 2012) =
320
- * FIX: Added compatibility for WordPress 2.8
321
- * 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.
322
- * FIX: Plugin should now work for plugins not using the 'wp_' DB prefix
323
- * FIX: Coauthors should no longer be alphabetically reordered when the post is updated
324
- * FIX: Plugin now used WordPress native AJAX calls to tighten security
325
- * DOCS: Added details about the new template tags
326
-
327
- = 1.1.5 (Apr. 26, 2009) =
328
- * FIX: Not searching Updated SQL query for autosuggest to search through first name, last name, and nickname
329
- * FIX: When editing an author, and clicking on a suggested author, the original author was not be removed
330
- * DOCS: Added code comments to javascript; more still to be added
331
- * DOCS: Updated readme information
332
-
333
- = 1.1.4 (Apr. 25, 2009) =
334
- * Disabled "New Author" output in suggest box, for now
335
- * Hopefully fixed SVN issue (if you're having trouble with the plugin, please delete the plugin and reinstall)
336
-
337
- = 1.1.3 (Apr. 23, 2009) =
338
- * Add blur event to disable input box
339
- * Limit only one edit at a time.
340
- * Checked basic cross-browser compatibility (Firefox 3 OS X, Safari 3 OS X, IE7 Vista).
341
- * Add suggest javascript plugin to Edit Page.
342
-
343
- = 1.1.2 (Apr. 19, 2009) =
344
- * Disabled form submit when enter pressed.
345
-
346
- = 1.1.1 (Apr. 15, 2009) =
347
- * Changed SQL query to return only contributor-level and above users.
348
-
349
- = 1.1.0 (Apr. 14, 2009) =
350
- * Initial beta release.
351
-
352
  == Installation ==
353
 
354
  1. IMPORTANT: Please disable the original Co-Authors plugin (if you are using it) before installing Co-Authors Plus
3
  Tags: authors, users, multiple authors, coauthors, multi-author, publishing
4
  Tested up to: 5.7
5
  Requires at least: 4.1
6
+ Stable tag: 3.4.6
7
 
8
  Assign multiple bylines to posts, pages, and custom post types via a search-as-you-type input box
9
 
46
  Yep! Guest authors can be disabled entirely through an apt filter. Having the following line load on `init` will do the trick:
47
  `add_filter( 'coauthors_guest_authors_enabled', '__return_false' )`
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  == Installation ==
50
 
51
  1. IMPORTANT: Please disable the original Co-Authors plugin (if you are using it) before installing Co-Authors Plus
template-tags.php CHANGED
@@ -4,7 +4,7 @@ function get_coauthors( $post_id = 0 ) {
4
  global $post, $post_ID, $coauthors_plus, $wpdb;
5
 
6
  $coauthors = array();
7
- $post_id = (int) $post_id;
8
  if ( ! $post_id && $post_ID ) {
9
  $post_id = $post_ID;
10
  }
@@ -18,13 +18,13 @@ function get_coauthors( $post_id = 0 ) {
18
  if ( is_array( $coauthor_terms ) && ! empty( $coauthor_terms ) ) {
19
  foreach ( $coauthor_terms as $coauthor ) {
20
  $coauthor_slug = preg_replace( '#^cap\-#', '', $coauthor->slug );
21
- $post_author = $coauthors_plus->get_coauthor_by( 'user_nicename', $coauthor_slug );
22
  // In case the user has been deleted while plugin was deactivated
23
  if ( ! empty( $post_author ) ) {
24
  $coauthors[] = $post_author;
25
  }
26
  }
27
- } else if ( ! $coauthors_plus->force_guest_authors ) {
28
  if ( $post && $post_id == $post->ID ) {
29
  $post_author = get_userdata( $post->post_author );
30
  } else {
@@ -43,8 +43,9 @@ function get_coauthors( $post_id = 0 ) {
43
 
44
  /**
45
  * Checks to see if the the specified user is author of the current global post or post (if specified)
 
46
  * @param object|int $user
47
- * @param int $post_id
48
  */
49
  function is_coauthor_for_post( $user, $post_id = 0 ) {
50
  global $post;
@@ -65,7 +66,7 @@ function is_coauthor_for_post( $user, $post_id = 0 ) {
65
  if ( is_numeric( $user ) ) {
66
  $user = get_userdata( $user );
67
  $user = $user->user_login;
68
- } else if ( isset( $user->user_login ) ) {
69
  $user = $user->user_login;
70
  } else {
71
  return false;
@@ -98,7 +99,7 @@ class CoAuthorsIterator {
98
  }
99
 
100
  $this->original_authordata = $this->current_author = $authordata;
101
- $this->authordata_array = get_coauthors( $postID );
102
 
103
  $this->count = count( $this->authordata_array );
104
  }
@@ -107,19 +108,19 @@ class CoAuthorsIterator {
107
  global $authordata;
108
  $this->position++;
109
 
110
- //At the end of the loop
111
  if ( $this->position > $this->count - 1 ) {
112
- $authordata = $this->current_author = $this->original_authordata;
113
  $this->position = -1;
114
  return false;
115
  }
116
 
117
- //At the beginning of the loop
118
  if ( 0 === $this->position && ! empty( $authordata ) ) {
119
  $this->original_authordata = $authordata;
120
  }
121
 
122
- $authordata = $this->current_author = $this->authordata_array[ $this->position ];
123
 
124
  return true;
125
  }
@@ -131,7 +132,7 @@ class CoAuthorsIterator {
131
  return $this->position;
132
  }
133
  function is_last() {
134
- return $this->position === $this->count - 1;
135
  }
136
  function is_first() {
137
  return $this->position === 0;
@@ -144,15 +145,15 @@ class CoAuthorsIterator {
144
  }
145
  }
146
 
147
- //Helper function for the following new template tags
148
  function coauthors__echo( $tag, $type = 'tag', $separators = array(), $tag_args = null, $echo = true ) {
149
 
150
  // Define the standard output separator. Constant support is for backwards compat.
151
  // @see https://github.com/danielbachhuber/Co-Authors-Plus/issues/12
152
- $default_before = ( defined( 'COAUTHORS_DEFAULT_BEFORE' ) ) ? COAUTHORS_DEFAULT_BEFORE : '';
153
- $default_between = ( defined( 'COAUTHORS_DEFAULT_BETWEEN' ) ) ? COAUTHORS_DEFAULT_BETWEEN : ', ';
154
- $default_between_last = ( defined( 'COAUTHORS_DEFAULT_BETWEEN_LAST' ) ) ? COAUTHORS_DEFAULT_BETWEEN_LAST : __( ' and ', 'co-authors-plus' );
155
- $default_after = ( defined( 'COAUTHORS_DEFAULT_AFTER' ) ) ? COAUTHORS_DEFAULT_AFTER : '';
156
 
157
  if ( ! isset( $separators['before'] ) || null === $separators['before'] ) {
158
  $separators['before'] = apply_filters( 'coauthors_default_before', $default_before );
@@ -169,7 +170,7 @@ function coauthors__echo( $tag, $type = 'tag', $separators = array(), $tag_args
169
 
170
  $output = '';
171
 
172
- $i = new CoAuthorsIterator();
173
  $output .= $separators['before'];
174
  $i->iterate();
175
  do {
@@ -201,7 +202,7 @@ function coauthors__echo( $tag, $type = 'tag', $separators = array(), $tag_args
201
  $output .= $separators['after'];
202
 
203
  if ( $echo ) {
204
- echo $output;
205
  }
206
 
207
  return $output;
@@ -215,15 +216,21 @@ function coauthors__echo( $tag, $type = 'tag', $separators = array(), $tag_args
215
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
216
  * @param string $before What should appear before the presentation of co-authors
217
  * @param string $after What should appear after the presentation of co-authors
218
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
219
  */
220
  function coauthors( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
221
- return coauthors__echo('display_name', 'field', array(
222
- 'between' => $between,
223
- 'betweenLast' => $betweenLast,
224
- 'before' => $before,
225
- 'after' => $after,
226
- ), null, $echo );
 
 
 
 
 
 
227
  }
228
 
229
  /**
@@ -234,7 +241,7 @@ function coauthors( $between = null, $betweenLast = null, $before = null, $after
234
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
235
  * @param string $before What should appear before the presentation of co-authors
236
  * @param string $after What should appear after the presentation of co-authors
237
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
238
  */
239
  function coauthors_posts_links( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
240
 
@@ -252,12 +259,18 @@ function coauthors_posts_links( $between = null, $betweenLast = null, $before =
252
  remove_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
253
  }
254
 
255
- $coauthors_posts_links = coauthors__echo( 'coauthors_posts_links_single', 'callback', array(
256
- 'between' => $between,
257
- 'betweenLast' => $betweenLast,
258
- 'before' => $before,
259
- 'after' => $after,
260
- ), null, $echo );
 
 
 
 
 
 
261
 
262
  if ( $modify_filter ) {
263
  add_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
@@ -282,16 +295,16 @@ function coauthors_posts_links_single( $author ) {
282
  );
283
  return;
284
  }
285
- $args = array(
286
  'before_html' => '',
287
- 'href' => get_author_posts_url( $author->ID, $author->user_nicename ),
288
- 'rel' => 'author',
289
- 'title' => sprintf( __( 'Posts by %s', 'co-authors-plus' ), apply_filters( 'the_author', $author->display_name ) ),
290
- 'class' => 'author url fn',
291
- 'text' => apply_filters( 'the_author', $author->display_name ),
292
- 'after_html' => '',
293
  );
294
- $args = apply_filters( 'coauthors_posts_link', $args, $author );
295
  $single_link = sprintf(
296
  '<a href="%1$s" title="%2$s" class="%3$s" rel="%4$s">%5$s</a>',
297
  esc_url( $args['href'] ),
@@ -310,15 +323,21 @@ function coauthors_posts_links_single( $author ) {
310
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
311
  * @param string $before What should appear before the presentation of co-authors
312
  * @param string $after What should appear after the presentation of co-authors
313
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
314
  */
315
  function coauthors_firstnames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
316
- return coauthors__echo('get_the_author_meta', 'tag', array(
317
- 'between' => $between,
318
- 'betweenLast' => $betweenLast,
319
- 'before' => $before,
320
- 'after' => $after,
321
- ), 'first_name', $echo );
 
 
 
 
 
 
322
  }
323
 
324
  /**
@@ -328,15 +347,21 @@ function coauthors_firstnames( $between = null, $betweenLast = null, $before = n
328
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
329
  * @param string $before What should appear before the presentation of co-authors
330
  * @param string $after What should appear after the presentation of co-authors
331
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
332
  */
333
  function coauthors_lastnames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
334
- return coauthors__echo( 'get_the_author_meta', 'tag', array(
335
- 'between' => $between,
336
- 'betweenLast' => $betweenLast,
337
- 'before' => $before,
338
- 'after' => $after,
339
- ), 'last_name', $echo );
 
 
 
 
 
 
340
  }
341
 
342
  /**
@@ -346,15 +371,21 @@ function coauthors_lastnames( $between = null, $betweenLast = null, $before = nu
346
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
347
  * @param string $before What should appear before the presentation of co-authors
348
  * @param string $after What should appear after the presentation of co-authors
349
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
350
  */
351
  function coauthors_nicknames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
352
- return coauthors__echo( 'get_the_author_meta', 'tag', array(
353
- 'between' => $between,
354
- 'betweenLast' => $betweenLast,
355
- 'before' => $before,
356
- 'after' => $after,
357
- ), 'nickname', $echo );
 
 
 
 
 
 
358
  }
359
 
360
  /**
@@ -364,7 +395,7 @@ function coauthors_nicknames( $between = null, $betweenLast = null, $before = nu
364
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
365
  * @param string $before What should appear before the presentation of co-authors
366
  * @param string $after What should appear after the presentation of co-authors
367
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
368
  */
369
  function coauthors_links( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
370
 
@@ -382,12 +413,18 @@ function coauthors_links( $between = null, $betweenLast = null, $before = null,
382
  remove_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
383
  }
384
 
385
- $coauthors_links = coauthors__echo( 'coauthors_links_single', 'callback', array(
386
- 'between' => $between,
387
- 'betweenLast' => $betweenLast,
388
- 'before' => $before,
389
- 'after' => $after,
390
- ), null, $echo );
 
 
 
 
 
 
391
 
392
  if ( $modify_filter ) {
393
  add_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
@@ -403,15 +440,21 @@ function coauthors_links( $between = null, $betweenLast = null, $before = null,
403
  * @param string $betweenLast Delimiter that should appear between the last two email addresses
404
  * @param string $before What should appear before the presentation of email addresses
405
  * @param string $after What should appear after the presentation of email addresses
406
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
407
  */
408
  function coauthors_emails( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
409
- return coauthors__echo( 'get_the_author_meta', 'tag', array(
410
- 'between' => $between,
411
- 'betweenLast' => $betweenLast,
412
- 'before' => $before,
413
- 'after' => $after,
414
- ), 'user_email', $echo );
 
 
 
 
 
 
415
  }
416
 
417
  /**
@@ -422,20 +465,20 @@ function coauthors_emails( $between = null, $betweenLast = null, $before = null,
422
  */
423
  function coauthors_links_single( $author ) {
424
  if ( 'guest-author' === $author->type && get_the_author_meta( 'website' ) ) {
425
- return sprintf( '<a href="%s" title="%s" rel="author external">%s</a>',
 
426
  esc_url( get_the_author_meta( 'website' ) ),
427
  esc_attr( sprintf( __( 'Visit %s&#8217;s website' ), esc_html( get_the_author() ) ) ),
428
  esc_html( get_the_author() )
429
  );
430
- }
431
- elseif ( get_the_author_meta( 'url' ) ) {
432
- return sprintf( '<a href="%s" title="%s" rel="author external">%s</a>',
433
  esc_url( get_the_author_meta( 'url' ) ),
434
  esc_attr( sprintf( __( 'Visit %s&#8217;s website' ), esc_html( get_the_author() ) ) ),
435
  esc_html( get_the_author() )
436
  );
437
- }
438
- else {
439
  return esc_html( get_the_author() );
440
  }
441
  }
@@ -447,15 +490,21 @@ function coauthors_links_single( $author ) {
447
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
448
  * @param string $before What should appear before the presentation of co-authors
449
  * @param string $after What should appear after the presentation of co-authors
450
- * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
451
  */
452
  function coauthors_ids( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
453
- return coauthors__echo( 'ID', 'field', array(
454
- 'between' => $between,
455
- 'betweenLast' => $betweenLast,
456
- 'before' => $before,
457
- 'after' => $after,
458
- ), null, $echo );
 
 
 
 
 
 
459
  }
460
 
461
  /**
@@ -467,55 +516,52 @@ function coauthors_ids( $between = null, $betweenLast = null, $before = null, $a
467
  * @return array $meta Value of the user field
468
  */
469
  function get_the_coauthor_meta( $field, $user_id = false ) {
470
- global $coauthors_plus;
471
-
472
- if ( ! $user_id ) {
473
- $coauthors = get_coauthors();
474
- }
475
- else {
476
- $coauthor_data = $coauthors_plus->get_coauthor_by( 'id', $user_id );
477
- $coauthors = array();
478
- if ( ! empty( $coauthor_data ) ) {
479
- $coauthors[] = $coauthor_data;
480
- }
481
- }
482
-
483
- $meta = array();
484
-
485
- if ( in_array( $field, array( 'login', 'pass', 'nicename', 'email', 'url', 'registered', 'activation_key', 'status' ) ) ) {
486
- $field = 'user_' . $field;
487
- }
488
-
489
- foreach ( $coauthors as $coauthor ) {
490
- $user_id = $coauthor->ID;
491
-
492
- if ( isset( $coauthor->type ) && 'user_url' === $field ) {
493
- if ( 'guest-author' === $coauthor->type ) {
494
- $field = 'website';
495
- }
496
- }
497
- else if ( 'website' === $field ) {
498
- $field = 'user_url';
499
- }
500
-
501
- if ( isset( $coauthor->$field ) ) {
502
- $meta[ $user_id ] = $coauthor->$field;
503
- }
504
- else {
505
- $meta[ $user_id ] = '';
506
- }
507
- }
508
-
509
- return $meta;
510
  }
511
 
512
 
513
  function the_coauthor_meta( $field, $user_id = 0 ) {
514
- // TODO: need before after options
515
- $coauthor_meta = get_the_coauthor_meta( $field, $user_id );
516
- foreach ( $coauthor_meta as $meta ) {
517
- echo esc_html( $meta );
518
- }
519
  }
520
 
521
  /**
@@ -527,6 +573,7 @@ function the_coauthor_meta( $field, $user_id = 0 ) {
527
  * feed_image (string) (''): If isn't empty, use this image to link to feeds.
528
  * echo (boolean) (true): Set to false to return the output, instead of echoing.
529
  * authors_with_posts_only (boolean) (false): If true, don't query for authors with no posts.
 
530
  * @param array $args The argument array.
531
  * @return null|string The output, if echo is set to false.
532
  */
@@ -534,32 +581,32 @@ function coauthors_wp_list_authors( $args = array() ) {
534
  global $coauthors_plus;
535
 
536
  $defaults = array(
537
- 'optioncount' => false,
538
- 'show_fullname' => false,
539
- 'hide_empty' => true,
540
- 'feed' => '',
541
- 'feed_image' => '',
542
- 'feed_type' => '',
543
- 'echo' => true,
544
- 'style' => 'list',
545
- 'html' => true,
546
- 'number' => 20, // A sane limit to start to avoid breaking all the things
547
- 'guest_authors_only' => false,
548
  'authors_with_posts_only' => false,
549
  );
550
 
551
- $args = wp_parse_args( $args, $defaults );
552
  $return = '';
553
 
554
- $term_args = array(
555
- 'orderby' => 'name',
556
- 'number' => (int) $args['number'],
557
- /*
558
- * Historically, this was set to always be `0` ignoring `$args['hide_empty']` value
559
- * To avoid any backwards incompatibility, inventing `authors_with_posts_only` that defaults to false
560
- */
561
- 'hide_empty' => (boolean) $args['authors_with_posts_only'],
562
- );
563
  $author_terms = get_terms( $coauthors_plus->coauthor_taxonomy, $term_args );
564
 
565
  $authors = array();
@@ -572,10 +619,9 @@ function coauthors_wp_list_authors( $args = array() ) {
572
  $authors[ $author_term->name ] = $coauthor;
573
 
574
  // only show guest authors if the $args is set to true
575
- if ( ! $args['guest_authors_only'] || $authors[ $author_term->name ]->type === 'guest-author' ) {
576
  $authors[ $author_term->name ]->post_count = $author_term->count;
577
- }
578
- else {
579
  unset( $authors[ $author_term->name ] );
580
  }
581
  }
@@ -585,7 +631,7 @@ function coauthors_wp_list_authors( $args = array() ) {
585
  // remove duplicates from linked accounts
586
  $linked_accounts = array_unique( array_column( $authors, 'linked_account' ) );
587
  foreach ( $linked_accounts as $linked_account ) {
588
- unset( $authors[$linked_account] );
589
  }
590
 
591
  foreach ( (array) $authors as $author ) {
@@ -655,13 +701,13 @@ function coauthors_wp_list_authors( $args = array() ) {
655
  }
656
 
657
  if ( $args['optioncount'] ) {
658
- $link .= ' ('. $author->post_count . ')';
659
  }
660
  }
661
 
662
  if ( ! ( 0 === $author->post_count && $args['hide_empty'] ) && 'list' == $args['style'] ) {
663
  $return .= $link . '</li>';
664
- } else if ( ! $args['hide_empty'] ) {
665
  $return .= $link . ', ';
666
  }
667
  }
@@ -671,7 +717,8 @@ function coauthors_wp_list_authors( $args = array() ) {
671
  if ( ! $args['echo'] ) {
672
  return $return;
673
  }
674
- echo $return;
 
675
  }
676
 
677
  /**
@@ -683,16 +730,16 @@ function coauthors_wp_list_authors( $args = array() ) {
683
  * This is a replacement for using get_avatar(), which only operates on email addresses and cannot differentiate
684
  * between Guest Authors (who may share an email) and regular user accounts
685
  *
686
- * @param object $coauthor The Co Author or Guest Author object.
687
- * @param int $size The desired size.
688
- * @param string $default Optional. URL for the default image or a default type. Accepts '404'
689
- * (return a 404 instead of a default image), 'retro' (8bit), 'monsterid'
690
- * (monster), 'wavatar' (cartoon face), 'indenticon' (the "quilt"),
691
- * 'mystery', 'mm', or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF),
692
- * or 'gravatar_default' (the Gravatar logo). Default is the value of the
693
- * 'avatar_default' option, with a fallback of 'mystery'.
694
- * @param string $alt Optional. Alternative text to use in &lt;img&gt; tag. Default false.
695
- * @param array|string $class Optional. Array or string of additional classes to add to the &lt;img&gt; element. Default null.
696
  * @return string The image tag for the avatar, or an empty string if none could be determined.
697
  */
698
  function coauthors_get_avatar( $coauthor, $size = 32, $default = '', $alt = false, $class = null ) {
4
  global $post, $post_ID, $coauthors_plus, $wpdb;
5
 
6
  $coauthors = array();
7
+ $post_id = (int) $post_id;
8
  if ( ! $post_id && $post_ID ) {
9
  $post_id = $post_ID;
10
  }
18
  if ( is_array( $coauthor_terms ) && ! empty( $coauthor_terms ) ) {
19
  foreach ( $coauthor_terms as $coauthor ) {
20
  $coauthor_slug = preg_replace( '#^cap\-#', '', $coauthor->slug );
21
+ $post_author = $coauthors_plus->get_coauthor_by( 'user_nicename', $coauthor_slug );
22
  // In case the user has been deleted while plugin was deactivated
23
  if ( ! empty( $post_author ) ) {
24
  $coauthors[] = $post_author;
25
  }
26
  }
27
+ } elseif ( ! $coauthors_plus->force_guest_authors ) {
28
  if ( $post && $post_id == $post->ID ) {
29
  $post_author = get_userdata( $post->post_author );
30
  } else {
43
 
44
  /**
45
  * Checks to see if the the specified user is author of the current global post or post (if specified)
46
+ *
47
  * @param object|int $user
48
+ * @param int $post_id
49
  */
50
  function is_coauthor_for_post( $user, $post_id = 0 ) {
51
  global $post;
66
  if ( is_numeric( $user ) ) {
67
  $user = get_userdata( $user );
68
  $user = $user->user_login;
69
+ } elseif ( isset( $user->user_login ) ) {
70
  $user = $user->user_login;
71
  } else {
72
  return false;
99
  }
100
 
101
  $this->original_authordata = $this->current_author = $authordata;
102
+ $this->authordata_array = get_coauthors( $postID );
103
 
104
  $this->count = count( $this->authordata_array );
105
  }
108
  global $authordata;
109
  $this->position++;
110
 
111
+ // At the end of the loop
112
  if ( $this->position > $this->count - 1 ) {
113
+ $authordata = $this->current_author = $this->original_authordata; // phpcs:ignore
114
  $this->position = -1;
115
  return false;
116
  }
117
 
118
+ // At the beginning of the loop
119
  if ( 0 === $this->position && ! empty( $authordata ) ) {
120
  $this->original_authordata = $authordata;
121
  }
122
 
123
+ $authordata = $this->current_author = $this->authordata_array[ $this->position ]; // phpcs:ignore
124
 
125
  return true;
126
  }
132
  return $this->position;
133
  }
134
  function is_last() {
135
+ return $this->position === $this->count - 1;
136
  }
137
  function is_first() {
138
  return $this->position === 0;
145
  }
146
  }
147
 
148
+ // Helper function for the following new template tags
149
  function coauthors__echo( $tag, $type = 'tag', $separators = array(), $tag_args = null, $echo = true ) {
150
 
151
  // Define the standard output separator. Constant support is for backwards compat.
152
  // @see https://github.com/danielbachhuber/Co-Authors-Plus/issues/12
153
+ $default_before = ( defined( 'COAUTHORS_DEFAULT_BEFORE' ) ) ? COAUTHORS_DEFAULT_BEFORE : '';
154
+ $default_between = ( defined( 'COAUTHORS_DEFAULT_BETWEEN' ) ) ? COAUTHORS_DEFAULT_BETWEEN : ', ';
155
+ $default_between_last = ( defined( 'COAUTHORS_DEFAULT_BETWEEN_LAST' ) ) ? COAUTHORS_DEFAULT_BETWEEN_LAST : __( ' and ', 'co-authors-plus' );
156
+ $default_after = ( defined( 'COAUTHORS_DEFAULT_AFTER' ) ) ? COAUTHORS_DEFAULT_AFTER : '';
157
 
158
  if ( ! isset( $separators['before'] ) || null === $separators['before'] ) {
159
  $separators['before'] = apply_filters( 'coauthors_default_before', $default_before );
170
 
171
  $output = '';
172
 
173
+ $i = new CoAuthorsIterator();
174
  $output .= $separators['before'];
175
  $i->iterate();
176
  do {
202
  $output .= $separators['after'];
203
 
204
  if ( $echo ) {
205
+ echo esc_html( $output );
206
  }
207
 
208
  return $output;
216
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
217
  * @param string $before What should appear before the presentation of co-authors
218
  * @param string $after What should appear after the presentation of co-authors
219
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
220
  */
221
  function coauthors( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
222
+ return coauthors__echo(
223
+ 'display_name',
224
+ 'field',
225
+ array(
226
+ 'between' => $between,
227
+ 'betweenLast' => $betweenLast,
228
+ 'before' => $before,
229
+ 'after' => $after,
230
+ ),
231
+ null,
232
+ $echo
233
+ );
234
  }
235
 
236
  /**
241
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
242
  * @param string $before What should appear before the presentation of co-authors
243
  * @param string $after What should appear after the presentation of co-authors
244
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
245
  */
246
  function coauthors_posts_links( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
247
 
259
  remove_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
260
  }
261
 
262
+ $coauthors_posts_links = coauthors__echo(
263
+ 'coauthors_posts_links_single',
264
+ 'callback',
265
+ array(
266
+ 'between' => $between,
267
+ 'betweenLast' => $betweenLast,
268
+ 'before' => $before,
269
+ 'after' => $after,
270
+ ),
271
+ null,
272
+ $echo
273
+ );
274
 
275
  if ( $modify_filter ) {
276
  add_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
295
  );
296
  return;
297
  }
298
+ $args = array(
299
  'before_html' => '',
300
+ 'href' => get_author_posts_url( $author->ID, $author->user_nicename ),
301
+ 'rel' => 'author',
302
+ 'title' => sprintf( __( 'Posts by %s', 'co-authors-plus' ), apply_filters( 'the_author', $author->display_name ) ),
303
+ 'class' => 'author url fn',
304
+ 'text' => apply_filters( 'the_author', $author->display_name ),
305
+ 'after_html' => '',
306
  );
307
+ $args = apply_filters( 'coauthors_posts_link', $args, $author );
308
  $single_link = sprintf(
309
  '<a href="%1$s" title="%2$s" class="%3$s" rel="%4$s">%5$s</a>',
310
  esc_url( $args['href'] ),
323
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
324
  * @param string $before What should appear before the presentation of co-authors
325
  * @param string $after What should appear after the presentation of co-authors
326
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
327
  */
328
  function coauthors_firstnames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
329
+ return coauthors__echo(
330
+ 'get_the_author_meta',
331
+ 'tag',
332
+ array(
333
+ 'between' => $between,
334
+ 'betweenLast' => $betweenLast,
335
+ 'before' => $before,
336
+ 'after' => $after,
337
+ ),
338
+ 'first_name',
339
+ $echo
340
+ );
341
  }
342
 
343
  /**
347
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
348
  * @param string $before What should appear before the presentation of co-authors
349
  * @param string $after What should appear after the presentation of co-authors
350
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
351
  */
352
  function coauthors_lastnames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
353
+ return coauthors__echo(
354
+ 'get_the_author_meta',
355
+ 'tag',
356
+ array(
357
+ 'between' => $between,
358
+ 'betweenLast' => $betweenLast,
359
+ 'before' => $before,
360
+ 'after' => $after,
361
+ ),
362
+ 'last_name',
363
+ $echo
364
+ );
365
  }
366
 
367
  /**
371
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
372
  * @param string $before What should appear before the presentation of co-authors
373
  * @param string $after What should appear after the presentation of co-authors
374
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
375
  */
376
  function coauthors_nicknames( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
377
+ return coauthors__echo(
378
+ 'get_the_author_meta',
379
+ 'tag',
380
+ array(
381
+ 'between' => $between,
382
+ 'betweenLast' => $betweenLast,
383
+ 'before' => $before,
384
+ 'after' => $after,
385
+ ),
386
+ 'nickname',
387
+ $echo
388
+ );
389
  }
390
 
391
  /**
395
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
396
  * @param string $before What should appear before the presentation of co-authors
397
  * @param string $after What should appear after the presentation of co-authors
398
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
399
  */
400
  function coauthors_links( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
401
 
413
  remove_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
414
  }
415
 
416
+ $coauthors_links = coauthors__echo(
417
+ 'coauthors_links_single',
418
+ 'callback',
419
+ array(
420
+ 'between' => $between,
421
+ 'betweenLast' => $betweenLast,
422
+ 'before' => $before,
423
+ 'after' => $after,
424
+ ),
425
+ null,
426
+ $echo
427
+ );
428
 
429
  if ( $modify_filter ) {
430
  add_filter( 'the_author', array( $coauthors_plus_template_filters, 'filter_the_author' ) );
440
  * @param string $betweenLast Delimiter that should appear between the last two email addresses
441
  * @param string $before What should appear before the presentation of email addresses
442
  * @param string $after What should appear after the presentation of email addresses
443
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
444
  */
445
  function coauthors_emails( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
446
+ return coauthors__echo(
447
+ 'get_the_author_meta',
448
+ 'tag',
449
+ array(
450
+ 'between' => $between,
451
+ 'betweenLast' => $betweenLast,
452
+ 'before' => $before,
453
+ 'after' => $after,
454
+ ),
455
+ 'user_email',
456
+ $echo
457
+ );
458
  }
459
 
460
  /**
465
  */
466
  function coauthors_links_single( $author ) {
467
  if ( 'guest-author' === $author->type && get_the_author_meta( 'website' ) ) {
468
+ return sprintf(
469
+ '<a href="%s" title="%s" rel="author external">%s</a>',
470
  esc_url( get_the_author_meta( 'website' ) ),
471
  esc_attr( sprintf( __( 'Visit %s&#8217;s website' ), esc_html( get_the_author() ) ) ),
472
  esc_html( get_the_author() )
473
  );
474
+ } elseif ( get_the_author_meta( 'url' ) ) {
475
+ return sprintf(
476
+ '<a href="%s" title="%s" rel="author external">%s</a>',
477
  esc_url( get_the_author_meta( 'url' ) ),
478
  esc_attr( sprintf( __( 'Visit %s&#8217;s website' ), esc_html( get_the_author() ) ) ),
479
  esc_html( get_the_author() )
480
  );
481
+ } else {
 
482
  return esc_html( get_the_author() );
483
  }
484
  }
490
  * @param string $betweenLast Delimiter that should appear between the last two co-authors
491
  * @param string $before What should appear before the presentation of co-authors
492
  * @param string $after What should appear after the presentation of co-authors
493
+ * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
494
  */
495
  function coauthors_ids( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
496
+ return coauthors__echo(
497
+ 'ID',
498
+ 'field',
499
+ array(
500
+ 'between' => $between,
501
+ 'betweenLast' => $betweenLast,
502
+ 'before' => $before,
503
+ 'after' => $after,
504
+ ),
505
+ null,
506
+ $echo
507
+ );
508
  }
509
 
510
  /**
516
  * @return array $meta Value of the user field
517
  */
518
  function get_the_coauthor_meta( $field, $user_id = false ) {
519
+ global $coauthors_plus;
520
+
521
+ if ( ! $user_id ) {
522
+ $coauthors = get_coauthors();
523
+ } else {
524
+ $coauthor_data = $coauthors_plus->get_coauthor_by( 'id', $user_id );
525
+ $coauthors = array();
526
+ if ( ! empty( $coauthor_data ) ) {
527
+ $coauthors[] = $coauthor_data;
528
+ }
529
+ }
530
+
531
+ $meta = array();
532
+
533
+ if ( in_array( $field, array( 'login', 'pass', 'nicename', 'email', 'url', 'registered', 'activation_key', 'status' ) ) ) {
534
+ $field = 'user_' . $field;
535
+ }
536
+
537
+ foreach ( $coauthors as $coauthor ) {
538
+ $user_id = $coauthor->ID;
539
+
540
+ if ( isset( $coauthor->type ) && 'user_url' === $field ) {
541
+ if ( 'guest-author' === $coauthor->type ) {
542
+ $field = 'website';
543
+ }
544
+ } elseif ( 'website' === $field ) {
545
+ $field = 'user_url';
546
+ }
547
+
548
+ if ( isset( $coauthor->$field ) ) {
549
+ $meta[ $user_id ] = $coauthor->$field;
550
+ } else {
551
+ $meta[ $user_id ] = '';
552
+ }
553
+ }
554
+
555
+ return $meta;
 
 
 
556
  }
557
 
558
 
559
  function the_coauthor_meta( $field, $user_id = 0 ) {
560
+ // TODO: need before after options
561
+ $coauthor_meta = get_the_coauthor_meta( $field, $user_id );
562
+ foreach ( $coauthor_meta as $meta ) {
563
+ echo esc_html( $meta );
564
+ }
565
  }
566
 
567
  /**
573
  * feed_image (string) (''): If isn't empty, use this image to link to feeds.
574
  * echo (boolean) (true): Set to false to return the output, instead of echoing.
575
  * authors_with_posts_only (boolean) (false): If true, don't query for authors with no posts.
576
+ *
577
  * @param array $args The argument array.
578
  * @return null|string The output, if echo is set to false.
579
  */
581
  global $coauthors_plus;
582
 
583
  $defaults = array(
584
+ 'optioncount' => false,
585
+ 'show_fullname' => false,
586
+ 'hide_empty' => true,
587
+ 'feed' => '',
588
+ 'feed_image' => '',
589
+ 'feed_type' => '',
590
+ 'echo' => true,
591
+ 'style' => 'list',
592
+ 'html' => true,
593
+ 'number' => 20, // A sane limit to start to avoid breaking all the things
594
+ 'guest_authors_only' => false,
595
  'authors_with_posts_only' => false,
596
  );
597
 
598
+ $args = wp_parse_args( $args, $defaults );
599
  $return = '';
600
 
601
+ $term_args = array(
602
+ 'orderby' => 'name',
603
+ 'number' => (int) $args['number'],
604
+ /*
605
+ * Historically, this was set to always be `0` ignoring `$args['hide_empty']` value
606
+ * To avoid any backwards incompatibility, inventing `authors_with_posts_only` that defaults to false
607
+ */
608
+ 'hide_empty' => (bool) $args['authors_with_posts_only'],
609
+ );
610
  $author_terms = get_terms( $coauthors_plus->coauthor_taxonomy, $term_args );
611
 
612
  $authors = array();
619
  $authors[ $author_term->name ] = $coauthor;
620
 
621
  // only show guest authors if the $args is set to true
622
+ if ( ! $args['guest_authors_only'] || $authors[ $author_term->name ]->type === 'guest-author' ) {
623
  $authors[ $author_term->name ]->post_count = $author_term->count;
624
+ } else {
 
625
  unset( $authors[ $author_term->name ] );
626
  }
627
  }
631
  // remove duplicates from linked accounts
632
  $linked_accounts = array_unique( array_column( $authors, 'linked_account' ) );
633
  foreach ( $linked_accounts as $linked_account ) {
634
+ unset( $authors[ $linked_account ] );
635
  }
636
 
637
  foreach ( (array) $authors as $author ) {
701
  }
702
 
703
  if ( $args['optioncount'] ) {
704
+ $link .= ' (' . $author->post_count . ')';
705
  }
706
  }
707
 
708
  if ( ! ( 0 === $author->post_count && $args['hide_empty'] ) && 'list' == $args['style'] ) {
709
  $return .= $link . '</li>';
710
+ } elseif ( ! $args['hide_empty'] ) {
711
  $return .= $link . ', ';
712
  }
713
  }
717
  if ( ! $args['echo'] ) {
718
  return $return;
719
  }
720
+
721
+ echo $return; // phpcs:ignore
722
  }
723
 
724
  /**
730
  * This is a replacement for using get_avatar(), which only operates on email addresses and cannot differentiate
731
  * between Guest Authors (who may share an email) and regular user accounts
732
  *
733
+ * @param object $coauthor The Co Author or Guest Author object.
734
+ * @param int $size The desired size.
735
+ * @param string $default Optional. URL for the default image or a default type. Accepts '404'
736
+ * (return a 404 instead of a default image), 'retro' (8bit), 'monsterid'
737
+ * (monster), 'wavatar' (cartoon face), 'indenticon' (the "quilt"),
738
+ * 'mystery', 'mm', or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF),
739
+ * or 'gravatar_default' (the Gravatar logo). Default is the value of the
740
+ * 'avatar_default' option, with a fallback of 'mystery'.
741
+ * @param string $alt Optional. Alternative text to use in &lt;img&gt; tag. Default false.
742
+ * @param array|string $class Optional. Array or string of additional classes to add to the &lt;img&gt; element. Default null.
743
  * @return string The image tag for the avatar, or an empty string if none could be determined.
744
  */
745
  function coauthors_get_avatar( $coauthor, $size = 32, $default = '', $alt = false, $class = null ) {
tests/fixtures/dummy-attachment.png ADDED
Binary file
tests/test-author-queried-object.php CHANGED
@@ -20,17 +20,19 @@ class Test_Author_Queried_Object extends CoAuthorsPlus_TestCase {
20
  */
21
  $author1 = $this->factory->user->create( array( 'user_login' => 'msauthor1' ) );
22
  $author2 = $this->factory->user->create( array( 'user_login' => 'msauthor2' ) );
23
- $blog2 = $this->factory->blog->create( array( 'user_id' => $author1 ) );
24
 
25
  switch_to_blog( $blog2 );
26
  $wp_rewrite->init();
27
 
28
- $blog2_post1 = $this->factory->post->create( array(
29
- 'post_status' => 'publish',
30
- 'post_content' => rand_str(),
31
- 'post_title' => rand_str(),
32
- 'post_author' => $author1,
33
- ) );
 
 
34
 
35
  /**
36
  * Author 1 is an author on the blog
20
  */
21
  $author1 = $this->factory->user->create( array( 'user_login' => 'msauthor1' ) );
22
  $author2 = $this->factory->user->create( array( 'user_login' => 'msauthor2' ) );
23
+ $blog2 = $this->factory->blog->create( array( 'user_id' => $author1 ) );
24
 
25
  switch_to_blog( $blog2 );
26
  $wp_rewrite->init();
27
 
28
+ $blog2_post1 = $this->factory->post->create(
29
+ array(
30
+ 'post_status' => 'publish',
31
+ 'post_content' => rand_str(),
32
+ 'post_title' => rand_str(),
33
+ 'post_author' => $author1,
34
+ )
35
+ );
36
 
37
  /**
38
  * Author 1 is an author on the blog
tests/test-author-queries.php CHANGED
@@ -3,143 +3,221 @@
3
  class Test_Author_Queries extends CoAuthorsPlus_TestCase {
4
 
5
  public function test__author_arg__user_is_post_author_query_as_post_author() {
6
- $author_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
7
- $author = get_userdata( $author_id );
8
- $post_id = $this->factory->post->create( array(
9
- 'post_author' => $author_id,
10
- 'post_status' => 'publish',
11
- 'post_type' => 'post',
12
- ) );
 
 
 
 
 
 
 
13
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
14
 
15
  wp_set_current_user( $author_id );
16
 
17
- $query = new WP_Query( array(
18
- 'author' => $author_id,
19
- ) );
 
 
20
 
21
  $this->assertEquals( 1, count( $query->posts ) );
22
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
23
  }
24
 
25
  public function test__author_arg__user_is_post_author() {
26
- $author_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
27
- $author = get_userdata( $author_id );
28
- $post_id = $this->factory->post->create( array(
29
- 'post_author' => $author_id,
30
- 'post_status' => 'publish',
31
- 'post_type' => 'post',
32
- ) );
 
 
 
 
 
 
 
33
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
34
 
35
- $query = new WP_Query( array(
36
- 'author' => $author_id,
37
- ) );
 
 
38
 
39
  $this->assertEquals( 1, count( $query->posts ) );
40
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
41
  }
42
 
43
  public function test__author_name_arg__user_is_post_author() {
44
- $author_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
45
- $author = get_userdata( $author_id );
46
- $post_id = $this->factory->post->create( array(
47
- 'post_author' => $author_id,
48
- 'post_status' => 'publish',
49
- 'post_type' => 'post',
50
- ) );
 
 
 
 
 
 
 
51
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
52
 
53
- $query = new WP_Query( array(
54
- 'author_name' => $author->user_login,
55
- ) );
 
 
56
 
57
  $this->assertEquals( 1, count( $query->posts ) );
58
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
59
  }
60
 
61
  public function test__author_name_arg__user_is_coauthor() {
62
- $author1_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
63
- $author1 = get_userdata( $author1_id );
64
- $author2_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'superman' ) );
65
- $author2 = get_userdata( $author2_id );
66
-
67
- $post_id = $this->factory->post->create( array(
68
- 'post_author' => $author1_id,
69
- 'post_status' => 'publish',
70
- 'post_type' => 'post',
71
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
72
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
73
 
74
- $query = new WP_Query( array(
75
- 'author_name' => $author2->user_login,
76
- ) );
 
 
77
 
78
  $this->assertEquals( 1, count( $query->posts ) );
79
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
80
  }
81
 
82
  public function test__author_arg__user_is_coauthor__author_arg() {
83
- $author1_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
84
- $author1 = get_userdata( $author1_id );
85
- $author2_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'superman' ) );
86
- $author2 = get_userdata( $author2_id );
87
-
88
- $post_id = $this->factory->post->create( array(
89
- 'post_author' => $author1_id,
90
- 'post_status' => 'publish',
91
- 'post_type' => 'post',
92
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
93
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
94
 
95
- $query = new WP_Query( array(
96
- 'author' => $author2_id,
97
- ) );
 
 
98
 
99
  $this->assertEquals( 1, count( $query->posts ) );
100
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
101
  }
102
 
103
  public function test__author_name_arg_plus_tax_query__user_is_post_author() {
104
- $author_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
105
- $author = get_userdata( $author_id );
106
- $post_id = $this->factory->post->create( array(
107
- 'post_author' => $author_id,
108
- 'post_status' => 'publish',
109
- 'post_type' => 'post',
110
- ) );
 
 
 
 
 
 
 
111
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
112
  wp_set_post_terms( $post_id, 'test', 'post_tag' );
113
 
114
- $query = new WP_Query( array(
115
- 'author_name' => $author->user_login,
116
- 'tag' => 'test',
117
- ) );
 
 
118
 
119
  $this->assertEquals( 1, count( $query->posts ) );
120
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
121
  }
122
 
123
  public function tests__author_name_arg_plus_tax_query__is_coauthor() {
124
- $author1_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'batman' ) );
125
- $author1 = get_userdata( $author1_id );
126
- $author2_id = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'superman' ) );
127
- $author2 = get_userdata( $author2_id );
128
-
129
- $post_id = $this->factory->post->create( array(
130
- 'post_author' => $author1_id,
131
- 'post_status' => 'publish',
132
- 'post_type' => 'post',
133
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
134
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
135
  wp_set_post_terms( $post_id, 'test', 'post_tag' );
136
 
137
- $query = new WP_Query( array(
138
- 'author_name' => $author2->user_login,
139
- 'tag' => 'test',
140
- ) );
 
 
141
 
142
  $this->assertEquals( 1, count( $query->posts ) );
143
- $this->assertEquals( $post_id, $query->posts[ 0 ]->ID );
144
  }
145
  }
3
  class Test_Author_Queries extends CoAuthorsPlus_TestCase {
4
 
5
  public function test__author_arg__user_is_post_author_query_as_post_author() {
6
+ $author_id = $this->factory->user->create(
7
+ array(
8
+ 'role' => 'author',
9
+ 'user_login' => 'batman',
10
+ )
11
+ );
12
+ $author = get_userdata( $author_id );
13
+ $post_id = $this->factory->post->create(
14
+ array(
15
+ 'post_author' => $author_id,
16
+ 'post_status' => 'publish',
17
+ 'post_type' => 'post',
18
+ )
19
+ );
20
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
21
 
22
  wp_set_current_user( $author_id );
23
 
24
+ $query = new WP_Query(
25
+ array(
26
+ 'author' => $author_id,
27
+ )
28
+ );
29
 
30
  $this->assertEquals( 1, count( $query->posts ) );
31
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
32
  }
33
 
34
  public function test__author_arg__user_is_post_author() {
35
+ $author_id = $this->factory->user->create(
36
+ array(
37
+ 'role' => 'author',
38
+ 'user_login' => 'batman',
39
+ )
40
+ );
41
+ $author = get_userdata( $author_id );
42
+ $post_id = $this->factory->post->create(
43
+ array(
44
+ 'post_author' => $author_id,
45
+ 'post_status' => 'publish',
46
+ 'post_type' => 'post',
47
+ )
48
+ );
49
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
50
 
51
+ $query = new WP_Query(
52
+ array(
53
+ 'author' => $author_id,
54
+ )
55
+ );
56
 
57
  $this->assertEquals( 1, count( $query->posts ) );
58
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
59
  }
60
 
61
  public function test__author_name_arg__user_is_post_author() {
62
+ $author_id = $this->factory->user->create(
63
+ array(
64
+ 'role' => 'author',
65
+ 'user_login' => 'batman',
66
+ )
67
+ );
68
+ $author = get_userdata( $author_id );
69
+ $post_id = $this->factory->post->create(
70
+ array(
71
+ 'post_author' => $author_id,
72
+ 'post_status' => 'publish',
73
+ 'post_type' => 'post',
74
+ )
75
+ );
76
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
77
 
78
+ $query = new WP_Query(
79
+ array(
80
+ 'author_name' => $author->user_login,
81
+ )
82
+ );
83
 
84
  $this->assertEquals( 1, count( $query->posts ) );
85
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
86
  }
87
 
88
  public function test__author_name_arg__user_is_coauthor() {
89
+ $author1_id = $this->factory->user->create(
90
+ array(
91
+ 'role' => 'author',
92
+ 'user_login' => 'batman',
93
+ )
94
+ );
95
+ $author1 = get_userdata( $author1_id );
96
+ $author2_id = $this->factory->user->create(
97
+ array(
98
+ 'role' => 'author',
99
+ 'user_login' => 'superman',
100
+ )
101
+ );
102
+ $author2 = get_userdata( $author2_id );
103
+
104
+ $post_id = $this->factory->post->create(
105
+ array(
106
+ 'post_author' => $author1_id,
107
+ 'post_status' => 'publish',
108
+ 'post_type' => 'post',
109
+ )
110
+ );
111
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
112
 
113
+ $query = new WP_Query(
114
+ array(
115
+ 'author_name' => $author2->user_login,
116
+ )
117
+ );
118
 
119
  $this->assertEquals( 1, count( $query->posts ) );
120
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
121
  }
122
 
123
  public function test__author_arg__user_is_coauthor__author_arg() {
124
+ $author1_id = $this->factory->user->create(
125
+ array(
126
+ 'role' => 'author',
127
+ 'user_login' => 'batman',
128
+ )
129
+ );
130
+ $author1 = get_userdata( $author1_id );
131
+ $author2_id = $this->factory->user->create(
132
+ array(
133
+ 'role' => 'author',
134
+ 'user_login' => 'superman',
135
+ )
136
+ );
137
+ $author2 = get_userdata( $author2_id );
138
+
139
+ $post_id = $this->factory->post->create(
140
+ array(
141
+ 'post_author' => $author1_id,
142
+ 'post_status' => 'publish',
143
+ 'post_type' => 'post',
144
+ )
145
+ );
146
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
147
 
148
+ $query = new WP_Query(
149
+ array(
150
+ 'author' => $author2_id,
151
+ )
152
+ );
153
 
154
  $this->assertEquals( 1, count( $query->posts ) );
155
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
156
  }
157
 
158
  public function test__author_name_arg_plus_tax_query__user_is_post_author() {
159
+ $author_id = $this->factory->user->create(
160
+ array(
161
+ 'role' => 'author',
162
+ 'user_login' => 'batman',
163
+ )
164
+ );
165
+ $author = get_userdata( $author_id );
166
+ $post_id = $this->factory->post->create(
167
+ array(
168
+ 'post_author' => $author_id,
169
+ 'post_status' => 'publish',
170
+ 'post_type' => 'post',
171
+ )
172
+ );
173
  $this->_cap->add_coauthors( $post_id, array( $author->user_login ) );
174
  wp_set_post_terms( $post_id, 'test', 'post_tag' );
175
 
176
+ $query = new WP_Query(
177
+ array(
178
+ 'author_name' => $author->user_login,
179
+ 'tag' => 'test',
180
+ )
181
+ );
182
 
183
  $this->assertEquals( 1, count( $query->posts ) );
184
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
185
  }
186
 
187
  public function tests__author_name_arg_plus_tax_query__is_coauthor() {
188
+ $author1_id = $this->factory->user->create(
189
+ array(
190
+ 'role' => 'author',
191
+ 'user_login' => 'batman',
192
+ )
193
+ );
194
+ $author1 = get_userdata( $author1_id );
195
+ $author2_id = $this->factory->user->create(
196
+ array(
197
+ 'role' => 'author',
198
+ 'user_login' => 'superman',
199
+ )
200
+ );
201
+ $author2 = get_userdata( $author2_id );
202
+
203
+ $post_id = $this->factory->post->create(
204
+ array(
205
+ 'post_author' => $author1_id,
206
+ 'post_status' => 'publish',
207
+ 'post_type' => 'post',
208
+ )
209
+ );
210
  $this->_cap->add_coauthors( $post_id, array( $author1->user_login, $author2->user_login ) );
211
  wp_set_post_terms( $post_id, 'test', 'post_tag' );
212
 
213
+ $query = new WP_Query(
214
+ array(
215
+ 'author_name' => $author2->user_login,
216
+ 'tag' => 'test',
217
+ )
218
+ );
219
 
220
  $this->assertEquals( 1, count( $query->posts ) );
221
+ $this->assertEquals( $post_id, $query->posts[0]->ID );
222
  }
223
  }
tests/test-coauthors-guest-authors.php CHANGED
@@ -2,21 +2,40 @@
2
 
3
  class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
4
 
 
 
5
  public function setUp() {
6
 
7
  parent::setUp();
8
 
9
- $this->admin1 = $this->factory->user->create_and_get( array( 'role' => 'administrator', 'user_login' => 'admin1' ) );
10
- $this->author1 = $this->factory->user->create_and_get( array( 'role' => 'author', 'user_login' => 'author1' ) );
11
- $this->editor1 = $this->factory->user->create_and_get( array( 'role' => 'editor', 'user_login' => 'editor1' ) );
12
-
13
- $this->post = $this->factory->post->create_and_get( array(
14
- 'post_author' => $this->author1->ID,
15
- 'post_status' => 'publish',
16
- 'post_content' => rand_str(),
17
- 'post_title' => rand_str(),
18
- 'post_type' => 'post',
19
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
  /**
@@ -116,30 +135,27 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
116
  $guest_author_obj = $coauthors_plus->guest_authors;
117
 
118
  // Checks when guest author does not have any thumbnail.
119
- $guest_author_id = $guest_author_obj->create( array(
120
- 'user_login' => 'author2',
121
- 'display_name' => 'author2',
122
- ) );
 
 
123
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
124
 
125
  $this->assertNull( $guest_author_obj->get_guest_author_thumbnail( $guest_author, 0 ) );
126
 
127
- // Checks when guest author has thumbnail.
128
- $filename = rand_str() . '.jpg';
129
- $contents = rand_str();
130
- $upload = wp_upload_bits( $filename, null, $contents );
131
-
132
- $this->assertTrue( empty( $upload['error'] ) );
133
-
134
- $attachment_id = $this->_make_attachment( $upload );
135
 
136
  set_post_thumbnail( $guest_author->ID, $attachment_id );
137
 
138
  $thumbnail = $guest_author_obj->get_guest_author_thumbnail( $guest_author, 0 );
139
 
140
- $this->assertContains( 'avatar-0', $thumbnail );
141
- $this->assertContains( $filename, $thumbnail );
142
- $this->assertContains( 'src="' . wp_get_attachment_url( $attachment_id ) . '"', $thumbnail );
 
 
143
  }
144
 
145
  /**
@@ -221,10 +237,12 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
221
  $this->assertEmpty( $guest_author_obj->get_all_linked_accounts() );
222
 
223
  // Checks when guest author ( not linked account ) exists.
224
- $guest_author_obj->create( array(
225
- 'user_login' => 'author2',
226
- 'display_name' => 'author2',
227
- ) );
 
 
228
 
229
  $this->assertEmpty( $guest_author_obj->get_all_linked_accounts() );
230
 
@@ -373,7 +391,7 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
373
  }
374
 
375
  $this->assertInstanceOf( 'WPDieException', $exception );
376
- $this->assertContains( esc_html( $expected ), $exception->getMessage() );
377
 
378
  // Checks when nonce is as expected.
379
  $_POST['_wpnonce'] = wp_create_nonce( 'delete-guest-author' );
@@ -425,7 +443,7 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
425
  }
426
 
427
  $this->assertInstanceOf( 'WPDieException', $exception );
428
- $this->assertContains( esc_html( $expected ), $exception->getMessage() );
429
 
430
  // Checks when current user has list_users capability.
431
  wp_set_current_user( $this->admin1->ID );
@@ -482,7 +500,7 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
482
  }
483
 
484
  $this->assertInstanceOf( 'WPDieException', $exception );
485
- $this->assertContains( esc_html( $expected ), $exception->getMessage() );
486
 
487
  // Checks when guest author exists.
488
  $_POST['id'] = $guest_author_obj->create_guest_author_from_user_id( $this->admin1->ID );
@@ -537,7 +555,7 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
537
  }
538
 
539
  $this->assertInstanceOf( 'WPDieException', $exception );
540
- $this->assertContains( esc_html( $expected ), $exception->getMessage() );
541
 
542
  // Restore current user from backup.
543
  wp_set_current_user( $current_user );
@@ -576,11 +594,11 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
576
 
577
  $guest_author_obj->handle_delete_guest_author_action();
578
 
579
- } catch( Exception $e ) {
580
 
581
- $this->assertContains( $guest_author_obj->parent_page, $e->getMessage() );
582
- $this->assertContains( 'page=view-guest-authors', $e->getMessage() );
583
- $this->assertContains( 'message=guest-author-deleted', $e->getMessage() );
584
  }
585
 
586
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
@@ -628,7 +646,7 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
628
  }
629
 
630
  $this->assertInstanceOf( 'WPDieException', $exception );
631
- $this->assertContains( esc_html( $expected ), $exception->getMessage() );
632
 
633
  // When coauthor exists.
634
  $_POST['leave-assigned-to'] = $this->author1->user_nicename;
@@ -641,9 +659,9 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
641
 
642
  } catch ( Exception $e ) {
643
 
644
- //$this->assertContains( $guest_author_obj->parent_page, $e->getMessage() );
645
- $this->assertContains( 'page=view-guest-authors', $e->getMessage() );
646
- $this->assertContains( 'message=guest-author-deleted', $e->getMessage() );
647
  }
648
 
649
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
@@ -687,9 +705,9 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
687
 
688
  } catch ( Exception $e ) {
689
 
690
- $this->assertContains( $guest_author_obj->parent_page, $e->getMessage() );
691
- $this->assertContains( 'page=view-guest-authors', $e->getMessage() );
692
- $this->assertContains( 'message=guest-author-deleted', $e->getMessage() );
693
  }
694
 
695
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
@@ -822,9 +840,11 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
822
  $guest_author2 = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id2 );
823
  $guest_author_term2 = $coauthors_plus->get_author_term( $guest_author2 );
824
 
825
- $post = $this->factory->post->create_and_get( array(
826
- 'post_author' => $author2->ID,
827
- ) );
 
 
828
 
829
  $response = $guest_author_obj->delete( $guest_author_id2, $guest_admin->linked_account );
830
 
@@ -846,10 +866,12 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
846
 
847
  $guest_author_obj = $coauthors_plus->guest_authors;
848
 
849
- $guest_author_id = $guest_author_obj->create( array(
850
- 'user_login' => 'guest_author',
851
- 'display_name' => 'guest_author',
852
- ) );
 
 
853
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
854
  $guest_author_term = $coauthors_plus->get_author_term( $guest_author );
855
 
@@ -874,10 +896,12 @@ class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
874
  $guest_admin_id = $guest_author_obj->create_guest_author_from_user_id( $this->admin1->ID );
875
  $guest_admin = $guest_author_obj->get_guest_author_by( 'ID', $guest_admin_id );
876
 
877
- $guest_author_id = $guest_author_obj->create( array(
878
- 'user_login' => 'guest_author',
879
- 'display_name' => 'guest_author',
880
- ) );
 
 
881
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
882
  $guest_author_term = $coauthors_plus->get_author_term( $guest_author );
883
 
2
 
3
  class Test_CoAuthors_Guest_Authors extends CoAuthorsPlus_TestCase {
4
 
5
+ use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
6
+
7
  public function setUp() {
8
 
9
  parent::setUp();
10
 
11
+ $this->admin1 = $this->factory->user->create_and_get(
12
+ array(
13
+ 'role' => 'administrator',
14
+ 'user_login' => 'admin1',
15
+ )
16
+ );
17
+ $this->author1 = $this->factory->user->create_and_get(
18
+ array(
19
+ 'role' => 'author',
20
+ 'user_login' => 'author1',
21
+ )
22
+ );
23
+ $this->editor1 = $this->factory->user->create_and_get(
24
+ array(
25
+ 'role' => 'editor',
26
+ 'user_login' => 'editor1',
27
+ )
28
+ );
29
+
30
+ $this->post = $this->factory->post->create_and_get(
31
+ array(
32
+ 'post_author' => $this->author1->ID,
33
+ 'post_status' => 'publish',
34
+ 'post_content' => rand_str(),
35
+ 'post_title' => rand_str(),
36
+ 'post_type' => 'post',
37
+ )
38
+ );
39
  }
40
 
41
  /**
135
  $guest_author_obj = $coauthors_plus->guest_authors;
136
 
137
  // Checks when guest author does not have any thumbnail.
138
+ $guest_author_id = $guest_author_obj->create(
139
+ array(
140
+ 'user_login' => 'author2',
141
+ 'display_name' => 'author2',
142
+ )
143
+ );
144
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
145
 
146
  $this->assertNull( $guest_author_obj->get_guest_author_thumbnail( $guest_author, 0 ) );
147
 
148
+ $attachment_id = $this->factory->attachment->create_upload_object( __DIR__ . '/fixtures/dummy-attachment.png' );
 
 
 
 
 
 
 
149
 
150
  set_post_thumbnail( $guest_author->ID, $attachment_id );
151
 
152
  $thumbnail = $guest_author_obj->get_guest_author_thumbnail( $guest_author, 0 );
153
 
154
+ $this->assertStringContainsString( 'avatar-0', $thumbnail );
155
+ // Checking for dummy-attachment instead of dummy-attachment.png, as filename might change to
156
+ // dummy-attachment-1.png, dummy-attachment-2.png, etc. when running multiple tests.
157
+ $this->assertStringContainsString( 'dummy-attachment', $thumbnail );
158
+ $this->assertStringContainsString( wp_get_attachment_url( $attachment_id ), $thumbnail );
159
  }
160
 
161
  /**
237
  $this->assertEmpty( $guest_author_obj->get_all_linked_accounts() );
238
 
239
  // Checks when guest author ( not linked account ) exists.
240
+ $guest_author_obj->create(
241
+ array(
242
+ 'user_login' => 'author2',
243
+ 'display_name' => 'author2',
244
+ )
245
+ );
246
 
247
  $this->assertEmpty( $guest_author_obj->get_all_linked_accounts() );
248
 
391
  }
392
 
393
  $this->assertInstanceOf( 'WPDieException', $exception );
394
+ $this->assertStringContainsString( esc_html( $expected ), $exception->getMessage() );
395
 
396
  // Checks when nonce is as expected.
397
  $_POST['_wpnonce'] = wp_create_nonce( 'delete-guest-author' );
443
  }
444
 
445
  $this->assertInstanceOf( 'WPDieException', $exception );
446
+ $this->assertStringContainsString( esc_html( $expected ), $exception->getMessage() );
447
 
448
  // Checks when current user has list_users capability.
449
  wp_set_current_user( $this->admin1->ID );
500
  }
501
 
502
  $this->assertInstanceOf( 'WPDieException', $exception );
503
+ $this->assertStringContainsString( esc_html( $expected ), $exception->getMessage() );
504
 
505
  // Checks when guest author exists.
506
  $_POST['id'] = $guest_author_obj->create_guest_author_from_user_id( $this->admin1->ID );
555
  }
556
 
557
  $this->assertInstanceOf( 'WPDieException', $exception );
558
+ $this->assertStringContainsString( esc_html( $expected ), $exception->getMessage() );
559
 
560
  // Restore current user from backup.
561
  wp_set_current_user( $current_user );
594
 
595
  $guest_author_obj->handle_delete_guest_author_action();
596
 
597
+ } catch ( Exception $e ) {
598
 
599
+ $this->assertStringContainsString( $guest_author_obj->parent_page, $e->getMessage() );
600
+ $this->assertStringContainsString( 'page=view-guest-authors', $e->getMessage() );
601
+ $this->assertStringContainsString( 'message=guest-author-deleted', $e->getMessage() );
602
  }
603
 
604
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
646
  }
647
 
648
  $this->assertInstanceOf( 'WPDieException', $exception );
649
+ $this->assertStringContainsString( esc_html( $expected ), $exception->getMessage() );
650
 
651
  // When coauthor exists.
652
  $_POST['leave-assigned-to'] = $this->author1->user_nicename;
659
 
660
  } catch ( Exception $e ) {
661
 
662
+ //$this->assertStringContainsString( $guest_author_obj->parent_page, $e->getMessage() );
663
+ $this->assertStringContainsString( 'page=view-guest-authors', $e->getMessage() );
664
+ $this->assertStringContainsString( 'message=guest-author-deleted', $e->getMessage() );
665
  }
666
 
667
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
705
 
706
  } catch ( Exception $e ) {
707
 
708
+ $this->assertStringContainsString( $guest_author_obj->parent_page, $e->getMessage() );
709
+ $this->assertStringContainsString( 'page=view-guest-authors', $e->getMessage() );
710
+ $this->assertStringContainsString( 'message=guest-author-deleted', $e->getMessage() );
711
  }
712
 
713
  remove_filter( 'wp_redirect', array( $this, 'catch_redirect_destination' ), 99 );
840
  $guest_author2 = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id2 );
841
  $guest_author_term2 = $coauthors_plus->get_author_term( $guest_author2 );
842
 
843
+ $post = $this->factory->post->create_and_get(
844
+ array(
845
+ 'post_author' => $author2->ID,
846
+ )
847
+ );
848
 
849
  $response = $guest_author_obj->delete( $guest_author_id2, $guest_admin->linked_account );
850
 
866
 
867
  $guest_author_obj = $coauthors_plus->guest_authors;
868
 
869
+ $guest_author_id = $guest_author_obj->create(
870
+ array(
871
+ 'user_login' => 'guest_author',
872
+ 'display_name' => 'guest_author',
873
+ )
874
+ );
875
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
876
  $guest_author_term = $coauthors_plus->get_author_term( $guest_author );
877
 
896
  $guest_admin_id = $guest_author_obj->create_guest_author_from_user_id( $this->admin1->ID );
897
  $guest_admin = $guest_author_obj->get_guest_author_by( 'ID', $guest_admin_id );
898
 
899
+ $guest_author_id = $guest_author_obj->create(
900
+ array(
901
+ 'user_login' => 'guest_author',
902
+ 'display_name' => 'guest_author',
903
+ )
904
+ );
905
  $guest_author = $guest_author_obj->get_guest_author_by( 'ID', $guest_author_id );
906
  $guest_author_term = $coauthors_plus->get_author_term( $guest_author );
907
 
tests/test-coauthors-plus.php CHANGED
@@ -6,16 +6,28 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
6
 
7
  parent::setUp();
8
 
9
- $this->author1 = $this->factory->user->create_and_get( array( 'role' => 'author', 'user_login' => 'author1' ) );
10
- $this->editor1 = $this->factory->user->create_and_get( array( 'role' => 'editor', 'user_login' => 'editor1' ) );
11
-
12
- $this->post = $this->factory->post->create_and_get( array(
13
- 'post_author' => $this->author1->ID,
14
- 'post_status' => 'publish',
15
- 'post_content' => rand_str(),
16
- 'post_title' => rand_str(),
17
- 'post_type' => 'post',
18
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
 
21
  /**
@@ -47,10 +59,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
47
 
48
  global $coauthors_plus;
49
 
50
- $guest_author_id = $coauthors_plus->guest_authors->create( array(
51
- 'user_login' => 'author2',
52
- 'display_name' => 'author2',
53
- ) );
 
 
54
 
55
  $coauthor = $coauthors_plus->get_coauthor_by( 'id', $guest_author_id );
56
 
@@ -200,9 +214,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
200
  $GLOBALS['current_screen'] = $screen;
201
 
202
  // Checks when current user is admin.
203
- $admin1 = $this->factory->user->create_and_get( array(
204
- 'role' => 'administrator',
205
- ) );
 
 
206
 
207
  wp_set_current_user( $admin1->ID );
208
 
@@ -248,9 +264,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
248
  $this->assertTrue( $coauthors_plus->current_user_can_set_authors() );
249
 
250
  // Checks when current user is super admin.
251
- $admin1 = $this->factory->user->create_and_get( array(
252
- 'role' => 'administrator',
253
- ) );
 
 
254
 
255
  grant_super_admin( $admin1->ID );
256
  wp_set_current_user( $admin1->ID );
@@ -289,9 +307,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
289
  $this->assertTrue( $coauthors_plus->current_user_can_set_authors( $this->post ) );
290
 
291
  // Checks when current user is super admin.
292
- $admin1 = $this->factory->user->create_and_get( array(
293
- 'role' => 'administrator',
294
- ) );
 
 
295
 
296
  grant_super_admin( $admin1->ID );
297
  wp_set_current_user( $admin1->ID );
@@ -315,9 +335,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
315
  $current_user = get_current_user_id();
316
 
317
  // Checking when current user is subscriber and filter is true/false.
318
- $subscriber1 = $this->factory->user->create_and_get( array(
319
- 'role' => 'subscriber',
320
- ) );
 
 
321
 
322
  $this->assertFalse( $coauthors_plus->current_user_can_set_authors( $this->post ) );
323
 
@@ -360,10 +382,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
360
  $this->assertArrayHasKey( $this->editor1->user_login, $authors );
361
 
362
  // Checks when search term is empty and any subscriber exists.
363
- $subscriber1 = $this->factory->user->create_and_get( array(
364
- 'role' => 'subscriber',
365
- 'user_login' => 'subscriber1'
366
- ) );
 
 
367
 
368
  $authors = $coauthors_plus->search_authors();
369
 
@@ -371,10 +395,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
371
  $this->assertArrayNotHasKey( $subscriber1->user_login, $authors );
372
 
373
  // Checks when search term is empty and any contributor exists.
374
- $contributor1 = $this->factory->user->create_and_get( array(
375
- 'role' => 'contributor',
376
- 'user_login' => 'contributor1'
377
- ) );
 
 
378
 
379
  $authors = $coauthors_plus->search_authors();
380
 
@@ -427,9 +453,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
427
  $this->assertArrayNotHasKey( 'admin', $authors );
428
 
429
  // Checks when any subscriber exists using ID but not author.
430
- $subscriber1 = $this->factory->user->create_and_get( array(
431
- 'role' => 'subscriber',
432
- ) );
 
 
433
 
434
  $this->assertEmpty( $coauthors_plus->search_authors( $subscriber1->ID ) );
435
  }
@@ -452,10 +480,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
452
  $this->assertArrayNotHasKey( $this->author1->user_login, $authors );
453
 
454
  // Checks when ignoring author1 but also exists one more author with similar kind of data.
455
- $author2 = $this->factory->user->create_and_get( array(
456
- 'role' => 'author',
457
- 'user_login' => 'author2'
458
- ) );
 
 
459
 
460
  $authors = $coauthors_plus->search_authors( '', $ignored_authors );
461
 
@@ -486,10 +516,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
486
  $this->assertEmpty( $coauthors_plus->search_authors( $this->author1->ID, $ignored_authors ) );
487
 
488
  // Checks when ignoring author1 but also exists one more author with similar kind of data.
489
- $author2 = $this->factory->user->create_and_get( array(
490
- 'role' => 'author',
491
- 'user_login' => 'author2',
492
- ) );
 
 
493
 
494
  $authors = $coauthors_plus->search_authors( 'author', $ignored_authors );
495
 
@@ -567,10 +599,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
567
  global $coauthors_plus;
568
 
569
  // Checks when term exists without linked account.
570
- $coauthor_id = $coauthors_plus->guest_authors->create( array(
571
- 'display_name' => 'guest',
572
- 'user_login' => 'guest',
573
- ) );
 
 
574
  $coauthor = $coauthors_plus->get_coauthor_by( 'id', $coauthor_id );
575
 
576
  $author_term = $coauthors_plus->get_author_term( $coauthor );
@@ -613,10 +647,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
613
  $this->assertEquals( $this->author1->display_name . ' ' . $this->author1->first_name . ' ' . $this->author1->last_name . ' ' . $this->author1->user_login . ' ' . $this->author1->ID . ' ' . $this->author1->user_email, $author_term->description );
614
 
615
  // Checks term description after updating user.
616
- wp_update_user( array(
617
- 'ID' => $this->author1->ID,
618
- 'first_name' => 'author1',
619
- ) );
 
 
620
 
621
  $author_term = $coauthors_plus->update_author_term( $this->author1 );
622
 
@@ -625,10 +661,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
625
  // Backup coauthor taxonomy.
626
  $taxonomy_backup = $coauthors_plus->coauthor_taxonomy;
627
 
628
- wp_update_user( array(
629
- 'ID' => $this->author1->ID,
630
- 'last_name' => 'author1',
631
- ) );
 
 
632
 
633
  // Checks with different taxonomy.
634
  $coauthors_plus->coauthor_taxonomy = 'abcd';
@@ -654,10 +692,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
654
  $this->assertEquals( $this->editor1->display_name . ' ' . $this->editor1->first_name . ' ' . $this->editor1->last_name . ' ' . $this->editor1->user_login . ' ' . $this->editor1->ID . ' ' . $this->editor1->user_email, $author_term->description );
655
 
656
  // Checks term description after updating user.
657
- wp_update_user( array(
658
- 'ID' => $this->editor1->ID,
659
- 'first_name' => 'editor1',
660
- ) );
 
 
661
 
662
  $author_term = $coauthors_plus->update_author_term( $this->editor1 );
663
 
@@ -666,10 +706,12 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase {
666
  // Backup coauthor taxonomy.
667
  $taxonomy_backup = $coauthors_plus->coauthor_taxonomy;
668
 
669
- wp_update_user( array(
670
- 'ID' => $this->editor1->ID,
671
- 'last_name' => 'editor1',
672
- ) );
 
 
673
 
674
  // Checks with different taxonomy.
675
  $coauthors_plus->coauthor_taxonomy = 'abcd';
6
 
7
  parent::setUp();
8
 
9
+ $this->author1 = $this->factory->user->create_and_get(
10
+ array(
11
+ 'role' => 'author',
12
+ 'user_login' => 'author1',
13
+ )
14
+ );
15
+ $this->editor1 = $this->factory->user->create_and_get(
16
+ array(
17
+ 'role' => 'editor',
18
+ 'user_login' => 'editor1',
19
+ )
20
+ );
21
+
22
+ $this->post = $this->factory->post->create_and_get(
23
+ array(
24
+ 'post_author' => $this->author1->ID,
25
+ 'post_status' => 'publish',
26
+ 'post_content' => rand_str(),
27
+ 'post_title' => rand_str(),
28
+ 'post_type' => 'post',
29
+ )
30
+ );
31
  }
32
 
33
  /**
59
 
60
  global $coauthors_plus;
61
 
62
+ $guest_author_id = $coauthors_plus->guest_authors->create(
63
+ array(
64
+ 'user_login' => 'author2',
65
+ 'display_name' => 'author2',
66
+ )
67
+ );
68
 
69
  $coauthor = $coauthors_plus->get_coauthor_by( 'id', $guest_author_id );
70
 
214
  $GLOBALS['current_screen'] = $screen;
215
 
216
  // Checks when current user is admin.
217
+ $admin1 = $this->factory->user->create_and_get(
218
+ array(
219
+ 'role' => 'administrator',
220
+ )
221
+ );
222
 
223
  wp_set_current_user( $admin1->ID );
224
 
264
  $this->assertTrue( $coauthors_plus->current_user_can_set_authors() );
265
 
266
  // Checks when current user is super admin.
267
+ $admin1 = $this->factory->user->create_and_get(
268
+ array(
269
+ 'role' => 'administrator',
270
+ )
271
+ );
272
 
273
  grant_super_admin( $admin1->ID );
274
  wp_set_current_user( $admin1->ID );
307
  $this->assertTrue( $coauthors_plus->current_user_can_set_authors( $this->post ) );
308
 
309
  // Checks when current user is super admin.
310
+ $admin1 = $this->factory->user->create_and_get(
311
+ array(
312
+ 'role' => 'administrator',
313
+ )
314
+ );
315
 
316
  grant_super_admin( $admin1->ID );
317
  wp_set_current_user( $admin1->ID );
335
  $current_user = get_current_user_id();
336
 
337
  // Checking when current user is subscriber and filter is true/false.
338
+ $subscriber1 = $this->factory->user->create_and_get(
339
+ array(
340
+ 'role' => 'subscriber',
341
+ )
342
+ );
343
 
344
  $this->assertFalse( $coauthors_plus->current_user_can_set_authors( $this->post ) );
345
 
382
  $this->assertArrayHasKey( $this->editor1->user_login, $authors );
383
 
384
  // Checks when search term is empty and any subscriber exists.
385
+ $subscriber1 = $this->factory->user->create_and_get(
386
+ array(
387
+ 'role' => 'subscriber',
388
+ 'user_login' => 'subscriber1',
389
+ )
390
+ );
391
 
392
  $authors = $coauthors_plus->search_authors();
393
 
395
  $this->assertArrayNotHasKey( $subscriber1->user_login, $authors );
396
 
397
  // Checks when search term is empty and any contributor exists.
398
+ $contributor1 = $this->factory->user->create_and_get(
399
+ array(
400
+ 'role' => 'contributor',
401
+ 'user_login' => 'contributor1',
402
+ )
403
+ );
404
 
405
  $authors = $coauthors_plus->search_authors();
406
 
453
  $this->assertArrayNotHasKey( 'admin', $authors );
454
 
455
  // Checks when any subscriber exists using ID but not author.
456
+ $subscriber1 = $this->factory->user->create_and_get(
457
+ array(
458
+ 'role' => 'subscriber',
459
+ )
460
+ );
461
 
462
  $this->assertEmpty( $coauthors_plus->search_authors( $subscriber1->ID ) );
463
  }
480
  $this->assertArrayNotHasKey( $this->author1->user_login, $authors );
481
 
482
  // Checks when ignoring author1 but also exists one more author with similar kind of data.
483
+ $author2 = $this->factory->user->create_and_get(
484
+ array(
485
+ 'role' => 'author',
486
+ 'user_login' => 'author2',
487
+ )
488
+ );
489
 
490
  $authors = $coauthors_plus->search_authors( '', $ignored_authors );
491
 
516
  $this->assertEmpty( $coauthors_plus->search_authors( $this->author1->ID, $ignored_authors ) );
517
 
518
  // Checks when ignoring author1 but also exists one more author with similar kind of data.
519
+ $author2 = $this->factory->user->create_and_get(
520
+ array(
521
+ 'role' => 'author',
522
+ 'user_login' => 'author2',
523
+ )
524
+ );
525
 
526
  $authors = $coauthors_plus->search_authors( 'author', $ignored_authors );
527
 
599
  global $coauthors_plus;
600
 
601
  // Checks when term exists without linked account.
602
+ $coauthor_id = $coauthors_plus->guest_authors->create(
603
+ array(
604
+ 'display_name' => 'guest',
605
+ 'user_login' => 'guest',
606
+ )
607
+ );
608
  $coauthor = $coauthors_plus->get_coauthor_by( 'id', $coauthor_id );
609
 
610
  $author_term = $coauthors_plus->get_author_term( $coauthor );
647
  $this->assertEquals( $this->author1->display_name . ' ' . $this->author1->first_name . ' ' . $this->author1->last_name . ' ' . $this->author1->user_login . ' ' . $this->author1->ID . ' ' . $this->author1->user_email, $author_term->description );
648
 
649
  // Checks term description after updating user.
650
+ wp_update_user(
651
+ array(
652
+ 'ID' => $this->author1->ID,
653
+ 'first_name' => 'author1',
654
+ )
655
+ );
656
 
657
  $author_term = $coauthors_plus->update_author_term( $this->author1 );
658
 
661
  // Backup coauthor taxonomy.
662
  $taxonomy_backup = $coauthors_plus->coauthor_taxonomy;
663
 
664
+ wp_update_user(
665
+ array(
666
+ 'ID' => $this->author1->ID,
667
+ 'last_name' => 'author1',
668
+ )
669
+ );
670
 
671
  // Checks with different taxonomy.
672
  $coauthors_plus->coauthor_taxonomy = 'abcd';
692
  $this->assertEquals( $this->editor1->display_name . ' ' . $this->editor1->first_name . ' ' . $this->editor1->last_name . ' ' . $this->editor1->user_login . ' ' . $this->editor1->ID . ' ' . $this->editor1->user_email, $author_term->description );
693
 
694
  // Checks term description after updating user.
695
+ wp_update_user(
696
+ array(
697
+ 'ID' => $this->editor1->ID,
698
+ 'first_name' => 'editor1',
699
+ )
700
+ );
701
 
702
  $author_term = $coauthors_plus->update_author_term( $this->editor1 );
703
 
706
  // Backup coauthor taxonomy.
707
  $taxonomy_backup = $coauthors_plus->coauthor_taxonomy;
708
 
709
+ wp_update_user(
710
+ array(
711
+ 'ID' => $this->editor1->ID,
712
+ 'last_name' => 'editor1',
713
+ )
714
+ );
715
 
716
  // Checks with different taxonomy.
717
  $coauthors_plus->coauthor_taxonomy = 'abcd';
tests/test-manage-coauthors.php CHANGED
@@ -5,46 +5,61 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
5
  public function setUp() {
6
  parent::setUp();
7
 
8
- $this->admin1 = $this->factory->user->create( array( 'role' => 'administrator', 'user_login' => 'admin1' ) );
9
- $this->author1 = $this->factory->user->create( array( 'role' => 'author', 'user_login' => 'author1' ) );
10
- $this->editor1 = $this->factory->user->create( array( 'role' => 'editor', 'user_login' => 'editor2' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  $post = array(
13
- 'post_author' => $this->author1,
14
- 'post_status' => 'publish',
15
- 'post_content' => rand_str(),
16
- 'post_title' => rand_str(),
17
- 'post_type' => 'post',
18
  );
19
 
20
  $this->author1_post1 = wp_insert_post( $post );
21
 
22
  $post = array(
23
- 'post_author' => $this->author1,
24
- 'post_status' => 'publish',
25
- 'post_content' => rand_str(),
26
- 'post_title' => rand_str(),
27
- 'post_type' => 'post',
28
  );
29
 
30
  $this->author1_post2 = wp_insert_post( $post );
31
 
32
  $page = array(
33
- 'post_author' => $this->author1,
34
- 'post_status' => 'publish',
35
- 'post_content' => rand_str(),
36
- 'post_title' => rand_str(),
37
- 'post_type' => 'page',
38
  );
39
 
40
  $this->author1_page1 = wp_insert_post( $page );
41
 
42
  $page = array(
43
- 'post_author' => $this->author1,
44
- 'post_status' => 'publish',
45
- 'post_content' => rand_str(),
46
- 'post_title' => rand_str(),
47
- 'post_type' => 'page',
48
  );
49
 
50
  $this->author1_page2 = wp_insert_post( $page );
@@ -158,15 +173,23 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
158
 
159
  global $coauthors_plus;
160
 
161
- $this->assertEquals( 10, has_filter( 'wp_insert_post_data', array(
162
- $coauthors_plus,
163
- 'coauthors_set_post_author_field',
164
- ) ) );
 
 
 
 
 
 
165
 
166
- $post_id = $this->factory->post->create( array(
167
- 'post_author' => $this->author1,
168
- 'post_type' => 'attachment',
169
- ) );
 
 
170
 
171
  $post = get_post( $post_id );
172
 
@@ -216,10 +239,12 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
216
 
217
  global $coauthors_plus;
218
 
219
- $user_id = $this->factory->user->create( array(
220
- 'user_login' => 'test_admin',
221
- 'user_nicename' => 'test_admiи',
222
- ) );
 
 
223
 
224
  $user = get_user_by( 'id', $user_id );
225
 
@@ -227,14 +252,17 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
227
  $post_backup = $_POST;
228
  $request_backup = $_REQUEST;
229
 
230
- $_REQUEST['coauthors-nonce'] = wp_create_nonce( 'coauthors-edit' );;
231
- $_POST['coauthors'] = array(
 
232
  $user->user_nicename,
233
  );
234
 
235
- $post_id = $this->factory->post->create( array(
236
- 'post_author' => $user_id,
237
- ) );
 
 
238
 
239
  $post = get_post( $post_id );
240
 
@@ -278,13 +306,14 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
278
  $post_backup = $_POST;
279
  $request_backup = $_REQUEST;
280
 
281
- $_REQUEST['coauthors-nonce'] = wp_create_nonce( 'coauthors-edit' );;
282
- $_POST['coauthors'] = array(
 
283
  $author1->user_nicename,
284
  );
285
 
286
  // Create guest author with linked account with user.
287
- $coauthors_plus->guest_authors = new CoAuthors_Guest_Authors;
288
  $coauthors_plus->guest_authors->create_guest_author_from_user_id( $this->author1 );
289
 
290
  $new_data = $coauthors_plus->coauthors_set_post_author_field( $data, $post_array );
@@ -345,15 +374,23 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
345
 
346
  global $coauthors_plus;
347
 
348
- $this->assertEquals( 10, has_action( 'save_post', array(
349
- $coauthors_plus,
350
- 'coauthors_update_post',
351
- ) ) );
 
 
 
 
 
 
352
 
353
- $post_id = $this->factory->post->create( array(
354
- 'post_author' => $this->author1,
355
- 'post_type' => 'attachment',
356
- ) );
 
 
357
 
358
  $post = get_post( $post_id );
359
  $return = $coauthors_plus->coauthors_update_post( $post_id, $post );
@@ -377,9 +414,11 @@ class Test_Manage_CoAuthors extends CoAuthorsPlus_TestCase {
377
  $admin1 = get_user_by( 'id', $this->admin1 );
378
  $author1 = get_user_by( 'id', $this->author1 );
379
 
380
- $post_id = $this->factory->post->create( array(
381
- 'post_author' => $this->admin1,
382
- ) );
 
 
383
 
384
  $post = get_post( $post_id );
385
 
5
  public function setUp() {
6
  parent::setUp();
7
 
8
+ $this->admin1 = $this->factory->user->create(
9
+ array(
10
+ 'role' => 'administrator',
11
+ 'user_login' => 'admin1',
12
+ )
13
+ );
14
+ $this->author1 = $this->factory->user->create(
15
+ array(
16
+ 'role' => 'author',
17
+ 'user_login' => 'author1',
18
+ )
19
+ );
20
+ $this->editor1 = $this->factory->user->create(
21
+ array(
22
+ 'role' => 'editor',
23
+ 'user_login' => 'editor2',
24
+ )
25
+ );
26
 
27
  $post = array(
28
+ 'post_author' => $this->author1,
29
+ 'post_status' => 'publish',
30
+ 'post_content' => rand_str(),
31
+ 'post_title' => rand_str(),
32
+ 'post_type' => 'post',
33
  );
34
 
35
  $this->author1_post1 = wp_insert_post( $post );
36
 
37
  $post = array(
38
+ 'post_author' => $this->author1,
39
+ 'post_status' => 'publish',
40
+ 'post_content' => rand_str(),
41
+ 'post_title' => rand_str(),
42
+ 'post_type' => 'post',
43
  );
44
 
45
  $this->author1_post2 = wp_insert_post( $post );
46
 
47
  $page = array(
48
+ 'post_author' => $this->author1,
49
+ 'post_status' => 'publish',
50
+ 'post_content' => rand_str(),
51
+ 'post_title' => rand_str(),
52
+ 'post_type' => 'page',
53
  );
54
 
55
  $this->author1_page1 = wp_insert_post( $page );
56
 
57
  $page = array(
58
+ 'post_author' => $this->author1,
59
+ 'post_status' => 'publish',
60
+ 'post_content' => rand_str(),
61
+ 'post_title' => rand_str(),
62
+ 'post_type' => 'page',
63
  );
64
 
65
  $this->author1_page2 = wp_insert_post( $page );
173
 
174
  global $coauthors_plus;
175
 
176
+ $this->assertEquals(
177
+ 10,
178
+ has_filter(
179
+ 'wp_insert_post_data',
180
+ array(
181
+ $coauthors_plus,
182
+ 'coauthors_set_post_author_field',
183
+ )
184
+ )
185
+ );
186
 
187
+ $post_id = $this->factory->post->create(
188
+ array(
189
+ 'post_author' => $this->author1,
190
+ 'post_type' => 'attachment',
191
+ )
192
+ );
193
 
194
  $post = get_post( $post_id );
195
 
239
 
240
  global $coauthors_plus;
241
 
242
+ $user_id = $this->factory->user->create(
243
+ array(
244
+ 'user_login' => 'test_admin',
245
+ 'user_nicename' => 'test_admiи',
246
+ )
247
+ );
248
 
249
  $user = get_user_by( 'id', $user_id );
250
 
252
  $post_backup = $_POST;
253
  $request_backup = $_REQUEST;
254
 
255
+ $_REQUEST['coauthors-nonce'] = wp_create_nonce( 'coauthors-edit' );
256
+
257
+ $_POST['coauthors'] = array(
258
  $user->user_nicename,
259
  );
260
 
261
+ $post_id = $this->factory->post->create(
262
+ array(
263
+ 'post_author' => $user_id,
264
+ )
265
+ );
266
 
267
  $post = get_post( $post_id );
268
 
306
  $post_backup = $_POST;
307
  $request_backup = $_REQUEST;
308
 
309
+ $_REQUEST['coauthors-nonce'] = wp_create_nonce( 'coauthors-edit' );
310
+
311
+ $_POST['coauthors'] = array(
312
  $author1->user_nicename,
313
  );
314
 
315
  // Create guest author with linked account with user.
316
+ $coauthors_plus->guest_authors = new CoAuthors_Guest_Authors();
317
  $coauthors_plus->guest_authors->create_guest_author_from_user_id( $this->author1 );
318
 
319
  $new_data = $coauthors_plus->coauthors_set_post_author_field( $data, $post_array );
374
 
375
  global $coauthors_plus;
376
 
377
+ $this->assertEquals(
378
+ 10,
379
+ has_action(
380
+ 'save_post',
381
+ array(
382
+ $coauthors_plus,
383
+ 'coauthors_update_post',
384
+ )
385
+ )
386
+ );
387
 
388
+ $post_id = $this->factory->post->create(
389
+ array(
390
+ 'post_author' => $this->author1,
391
+ 'post_type' => 'attachment',
392
+ )
393
+ );
394
 
395
  $post = get_post( $post_id );
396
  $return = $coauthors_plus->coauthors_update_post( $post_id, $post );
414
  $admin1 = get_user_by( 'id', $this->admin1 );
415
  $author1 = get_user_by( 'id', $this->author1 );
416
 
417
+ $post_id = $this->factory->post->create(
418
+ array(
419
+ 'post_author' => $this->admin1,
420
+ )
421
+ );
422
 
423
  $post = get_post( $post_id );
424
 
tests/test-template-tags.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  class Test_Template_Tags extends CoAuthorsPlus_TestCase {
4
 
 
 
5
  public function setUp() {
6
 
7
  parent::setUp();
@@ -11,18 +13,30 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
11
  * we need CoAuthors_Template_Filters object to check 'the_author' filter.
12
  */
13
  global $coauthors_plus_template_filters;
14
- $coauthors_plus_template_filters = new CoAuthors_Template_Filters;
15
-
16
- $this->author1 = $this->factory->user->create_and_get( array( 'role' => 'author', 'user_login' => 'author1' ) );
17
- $this->editor1 = $this->factory->user->create_and_get( array( 'role' => 'editor', 'user_login' => 'editor1' ) );
18
-
19
- $this->post = $this->factory->post->create_and_get( array(
20
- 'post_author' => $this->author1->ID,
21
- 'post_status' => 'publish',
22
- 'post_content' => rand_str(),
23
- 'post_title' => rand_str(),
24
- 'post_type' => 'post',
25
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
 
28
  /**
@@ -44,23 +58,23 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
44
  // Checks for single post author.
45
  $single_cpl = coauthors_posts_links( null, null, null, null, false );
46
 
47
- $this->assertContains( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $single_cpl, 'Author link not found.' );
48
- $this->assertContains( $this->author1->display_name, $single_cpl, 'Author name not found.' );
49
 
50
  // Checks for multiple post author.
51
  $coauthors_plus->add_coauthors( $this->post->ID, array( $this->editor1->user_login ), true );
52
 
53
  $multiple_cpl = coauthors_posts_links( null, null, null, null, false );
54
 
55
- $this->assertContains( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $multiple_cpl, 'Main author link not found.' );
56
- $this->assertContains( $this->author1->display_name, $multiple_cpl, 'Main author name not found.' );
57
 
58
  // Here we are checking author name should not be more then one time.
59
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
60
  $this->assertEquals( 1, substr_count( $multiple_cpl, ">{$this->author1->display_name}<" ) );
61
- $this->assertContains( ' and ', $multiple_cpl, 'Coauthors name separator is not matched.' );
62
- $this->assertContains( 'href="' . get_author_posts_url( $this->editor1->ID, $this->editor1->user_nicename ) . '"', $multiple_cpl, 'Coauthor link not found.' );
63
- $this->assertContains( $this->editor1->display_name, $multiple_cpl, 'Coauthor name not found.' );
64
 
65
  // Here we are checking editor name should not be more then one time.
66
  // Asserting ">{$this->editor1->display_name}<" because "$this->editor1->display_name" can be multiple times like in href, title, etc.
@@ -68,12 +82,18 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
68
 
69
  $multiple_cpl = coauthors_links( null, ' or ', null, null, false );
70
 
71
- $this->assertContains( ' or ', $multiple_cpl, 'Coauthors name separator is not matched.' );
72
-
73
- $this->assertEquals( 10, has_filter( 'the_author', array(
74
- $coauthors_plus_template_filters,
75
- 'filter_the_author',
76
- ) ) );
 
 
 
 
 
 
77
 
78
  // Restore backed up post to global.
79
  $GLOBALS['post'] = $post_backup;
@@ -105,20 +125,26 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
105
 
106
  $multiple_cpl = coauthors_links( null, null, null, null, false );
107
 
108
- $this->assertContains( $this->author1->display_name, $multiple_cpl, 'Main author name not found.' );
109
  $this->assertEquals( 1, substr_count( $multiple_cpl, $this->author1->display_name ) );
110
- $this->assertContains( ' and ', $multiple_cpl, 'Coauthors name separator is not matched.' );
111
- $this->assertContains( $this->editor1->display_name, $multiple_cpl, 'Coauthor name not found.' );
112
  $this->assertEquals( 1, substr_count( $multiple_cpl, $this->editor1->display_name ) );
113
 
114
  $multiple_cpl = coauthors_links( null, ' or ', null, null, false );
115
 
116
- $this->assertContains( ' or ', $multiple_cpl, 'Coauthors name separator is not matched.' );
117
-
118
- $this->assertEquals( 10, has_filter( 'the_author', array(
119
- $coauthors_plus_template_filters,
120
- 'filter_the_author',
121
- ) ) );
 
 
 
 
 
 
122
 
123
  // Restore backed up post to global.
124
  $GLOBALS['post'] = $post_backup;
@@ -148,10 +174,13 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
148
 
149
  // Compare multiple authors.
150
  $coauthors_plus->add_coauthors( $this->post->ID, array( $this->editor1->user_login ), true );
151
- $this->assertEquals( array(
152
- $this->author1->ID,
153
- $this->editor1->ID,
154
- ), wp_list_pluck( get_coauthors( $this->post->ID ), 'ID' ) );
 
 
 
155
  }
156
 
157
  /**
@@ -182,9 +211,11 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
182
  $this->assertEmpty( get_coauthors() );
183
 
184
  $user_id = $this->factory->user->create();
185
- $post = $this->factory->post->create_and_get( array(
186
- 'post_author' => $user_id,
187
- ) );
 
 
188
 
189
  $this->assertEquals( array( $user_id ), wp_list_pluck( get_coauthors(), 'ID' ) );
190
 
@@ -361,8 +392,8 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
361
 
362
  $author_link = coauthors_posts_links_single( $this->author1 );
363
 
364
- $this->assertContains( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $author_link, 'Author link not found.' );
365
- $this->assertContains( $this->author1->display_name, $author_link, 'Author name not found.' );
366
 
367
  // Here we are checking author name should not be more then one time.
368
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
@@ -408,12 +439,16 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
408
 
409
  // Checking when first name is set for user.
410
  $first_name = 'Test';
411
- $user_id = $this->factory->user->create( array(
412
- 'first_name' => $first_name,
413
- ) );
414
- $post = $this->factory->post->create_and_get( array(
415
- 'post_author' => $user_id,
416
- ) );
 
 
 
 
417
 
418
  $first_names = coauthors_firstnames( null, null, null, null, false );
419
 
@@ -459,12 +494,16 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
459
 
460
  // Checking when last name is set for user.
461
  $last_name = 'Test';
462
- $user_id = $this->factory->user->create( array(
463
- 'last_name' => $last_name,
464
- ) );
465
- $post = $this->factory->post->create_and_get( array(
466
- 'post_author' => $user_id,
467
- ) );
 
 
 
 
468
 
469
  $last_names = coauthors_lastnames( null, null, null, null, false );
470
 
@@ -510,12 +549,16 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
510
 
511
  // Checking when nickname is set for user.
512
  $nick_name = 'Test';
513
- $user_id = $this->factory->user->create( array(
514
- 'nickname' => $nick_name,
515
- ) );
516
- $post = $this->factory->post->create_and_get( array(
517
- 'post_author' => $user_id,
518
- ) );
 
 
 
 
519
 
520
  $nick_names = coauthors_nicknames( null, null, null, null, false );
521
 
@@ -559,12 +602,16 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
559
  $this->assertEquals( '<span>' . $this->author1->user_email . '</span><span>' . $this->editor1->user_email . '</span>', $emails );
560
 
561
  $email = 'test@example.org';
562
- $user_id = $this->factory->user->create( array(
563
- 'user_email' => $email,
564
- ) );
565
- $post = $this->factory->post->create_and_get( array(
566
- 'post_author' => $user_id,
567
- ) );
 
 
 
 
568
 
569
  $emails = coauthors_emails( null, null, null, null, false );
570
 
@@ -590,23 +637,28 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
590
 
591
  // Backing up global author data.
592
  $authordata_backup = $authordata;
593
- $authordata = $this->author1;
594
 
595
  // Shows that it's necessary to set $authordata to $this->author1
596
  $this->assertEquals( $authordata, $this->author1, 'Global $authordata not matching expected $this->author1.' );
597
-
598
  $this->author1->type = 'guest-author';
599
 
600
  $this->assertEquals( get_the_author_link(), coauthors_links_single( $this->author1 ), 'Co-Author link generation differs from Core author link one (without user_url)' );
601
-
602
- wp_update_user( array( 'ID' => $this->author1->ID, 'user_url' => 'example.org' ) );
 
 
 
 
 
603
  $authordata = get_userdata( $this->author1->ID ); // Because wp_update_user flushes cache, but does not update global var
604
-
605
  $this->assertEquals( get_the_author_link(), coauthors_links_single( $this->author1 ), 'Co-Author link generation differs from Core author link one (with user_url)' );
606
 
607
  $author_link = coauthors_links_single( $this->author1 );
608
- $this->assertContains( get_the_author_meta( 'url' ), $author_link, 'Author url not found in link.' );
609
- $this->assertContains( get_the_author(), $author_link, 'Author name not found in link.' );
610
 
611
  // Here we are checking author name should not be more then one time.
612
  // Asserting ">get_the_author()<" because "get_the_author()" can be multiple times like in href, title, etc.
@@ -636,16 +688,18 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
636
  // Backing up global author data.
637
  $authordata_backup = $authordata;
638
 
639
- $user_id = $this->factory->user->create( array(
640
- 'user_url' => 'example.org',
641
- ) );
 
 
642
  $user = get_user_by( 'id', $user_id );
643
 
644
  $authordata = $user;
645
  $author_link = coauthors_links_single( $user );
646
 
647
- $this->assertContains( get_the_author_meta( 'url' ), $author_link, 'Author link not found.' );
648
- $this->assertContains( get_the_author(), $author_link, 'Author name not found.' );
649
 
650
  // Here we are checking author name should not be more then one time.
651
  // Asserting ">get_the_author()<" because "get_the_author()" can be multiple times like in href, title, etc.
@@ -772,8 +826,8 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
772
 
773
  $coauthors = coauthors_wp_list_authors( $args );
774
 
775
- $this->assertContains( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $coauthors, 'Author link not found.' );
776
- $this->assertContains( $this->author1->display_name, $coauthors, 'Author name not found.' );
777
 
778
  $coauthors = coauthors_wp_list_authors( $args );
779
 
@@ -784,16 +838,16 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
784
 
785
  $coauthors = coauthors_wp_list_authors( $args );
786
 
787
- $this->assertContains( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $coauthors, 'Main author link not found.' );
788
- $this->assertContains( $this->author1->display_name, $coauthors, 'Main author name not found.' );
789
 
790
  // Here we are checking author name should not be more then one time.
791
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
792
  $this->assertEquals( 1, substr_count( $coauthors, ">{$this->author1->display_name}<" ) );
793
 
794
- $this->assertContains( '</li><li>', $coauthors, 'Coauthors name separator is not matched.' );
795
- $this->assertContains( 'href="' . get_author_posts_url( $this->editor1->ID, $this->editor1->user_nicename ) . '"', $coauthors, 'Coauthor link not found.' );
796
- $this->assertContains( $this->editor1->display_name, $coauthors, 'Coauthor name not found.' );
797
 
798
  // Here we are checking editor name should not be more then one time.
799
  // Asserting ">{$this->editor1->display_name}<" because "$this->editor1->display_name" can be multiple times like in href, title, etc.
@@ -807,10 +861,15 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
807
  */
808
  public function test_coauthors_wp_list_authors_for_optioncount() {
809
 
810
- $this->assertContains( '(' . count_user_posts( $this->author1->ID ) . ')', coauthors_wp_list_authors( array(
811
- 'echo' => false,
812
- 'optioncount' => true,
813
- ) ) );
 
 
 
 
 
814
  }
815
 
816
  /**
@@ -825,18 +884,22 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
825
  'show_fullname' => true,
826
  );
827
 
828
- $this->assertContains( $this->author1->display_name, coauthors_wp_list_authors( $args ) );
829
 
830
- $user = $this->factory->user->create_and_get( array(
831
- 'first_name' => 'First',
832
- 'last_name' => 'Last',
833
- ) );
 
 
834
 
835
- $this->factory->post->create( array(
836
- 'post_author' => $user->ID,
837
- ) );
 
 
838
 
839
- $this->assertContains( "{$user->user_firstname} {$user->user_lastname}", coauthors_wp_list_authors( $args ) );
840
  }
841
 
842
  /**
@@ -848,15 +911,22 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
848
 
849
  global $coauthors_plus;
850
 
851
- $coauthors_plus->guest_authors->create( array(
852
- 'user_login' => 'author2',
853
- 'display_name' => 'author2',
854
- ) );
 
 
855
 
856
- $this->assertContains( 'author2', coauthors_wp_list_authors( array(
857
- 'echo' => false,
858
- 'hide_empty' => false,
859
- ) ) );
 
 
 
 
 
860
  }
861
 
862
  /**
@@ -867,13 +937,15 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
867
  public function test_coauthors_wp_list_authors_for_feed() {
868
 
869
  $feed_text = 'link to feed';
870
- $coauthors = coauthors_wp_list_authors( array(
871
- 'echo' => false,
872
- 'feed' => $feed_text,
873
- ) );
 
 
874
 
875
- $this->assertContains( esc_url( get_author_feed_link( $this->author1->ID ) ), $coauthors );
876
- $this->assertContains( $feed_text, $coauthors );
877
  }
878
 
879
  /**
@@ -884,13 +956,15 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
884
  public function test_coauthors_wp_list_authors_for_feed_image() {
885
 
886
  $feed_image = WP_TESTS_DOMAIN . '/path/to/a/graphic.png';
887
- $coauthors = coauthors_wp_list_authors( array(
888
- 'echo' => false,
889
- 'feed_image' => $feed_image,
890
- ) );
 
 
891
 
892
- $this->assertContains( esc_url( get_author_feed_link( $this->author1->ID ) ), $coauthors );
893
- $this->assertContains( $feed_image, $coauthors );
894
  }
895
 
896
  /**
@@ -902,15 +976,17 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
902
 
903
  $feed_type = 'atom';
904
  $feed_text = 'link to feed';
905
- $coauthors = coauthors_wp_list_authors( array(
906
- 'echo' => false,
907
- 'feed_type' => $feed_type,
908
- 'feed' => $feed_text,
909
- ) );
910
-
911
- $this->assertContains( esc_url( get_author_feed_link( $this->author1->ID, $feed_type ) ), $coauthors );
912
- $this->assertContains( $feed_type, $coauthors );
913
- $this->assertContains( $feed_text, $coauthors );
 
 
914
  }
915
 
916
  /**
@@ -920,10 +996,12 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
920
  */
921
  public function test_coauthors_wp_list_authors_for_style() {
922
 
923
- $coauthors = coauthors_wp_list_authors( array(
924
- 'echo' => false,
925
- 'style' => 'none',
926
- ) );
 
 
927
 
928
  $this->assertNotContains( '<li>', $coauthors );
929
  $this->assertNotContains( '</li>', $coauthors );
@@ -966,10 +1044,12 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
966
 
967
  $this->assertEmpty( coauthors_wp_list_authors( $args ) );
968
 
969
- $guest_author_id = $coauthors_plus->guest_authors->create( array(
970
- 'user_login' => 'author2',
971
- 'display_name' => 'author2',
972
- ) );
 
 
973
 
974
  $this->assertEmpty( coauthors_wp_list_authors( $args ) );
975
 
@@ -977,7 +1057,7 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
977
 
978
  $coauthors_plus->add_coauthors( $this->post->ID, array( $guest_author->user_login ), true );
979
 
980
- $this->assertContains( $guest_author->display_name, coauthors_wp_list_authors( $args ) );
981
  }
982
 
983
  /**
@@ -988,6 +1068,7 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
988
  public function test_coauthors_get_avatar_default() {
989
 
990
  $this->assertEmpty( coauthors_get_avatar( $this->author1->ID ) );
 
991
  $this->assertEquals( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*'( loading='[^']*')?/>$|", coauthors_get_avatar( $this->author1 ) ), 1 );
992
  }
993
 
@@ -1000,30 +1081,27 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
1000
 
1001
  global $coauthors_plus;
1002
 
1003
- $guest_author_id = $coauthors_plus->guest_authors->create( array(
1004
- 'user_login' => 'author2',
1005
- 'display_name' => 'author2',
1006
- ) );
 
 
1007
 
1008
  $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'id', $guest_author_id );
 
1009
 
1010
  $this->assertEquals( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*'( loading='[^']*')?/>$|", coauthors_get_avatar( $guest_author ) ), 1 );
1011
 
1012
- $filename = rand_str() . '.jpg';
1013
- $contents = rand_str();
1014
- $upload = wp_upload_bits( $filename, null, $contents );
1015
-
1016
- $this->assertTrue( empty( $upload['error'] ) );
1017
-
1018
- $attachment_id = $this->_make_attachment( $upload );
1019
-
1020
  set_post_thumbnail( $guest_author->ID, $attachment_id );
1021
 
1022
  $avatar = coauthors_get_avatar( $guest_author );
1023
  $attachment_url = wp_get_attachment_url( $attachment_id );
1024
 
1025
- $this->assertContains( $filename, $avatar );
1026
- $this->assertContains( 'src="' . $attachment_url . '"', $avatar );
 
 
1027
  }
1028
 
1029
  /**
@@ -1035,10 +1113,12 @@ class Test_Template_Tags extends CoAuthorsPlus_TestCase {
1035
 
1036
  global $coauthors_plus;
1037
 
1038
- $guest_author_id = $coauthors_plus->guest_authors->create( array(
1039
- 'user_login' => 'author2',
1040
- 'display_name' => 'author2',
1041
- ) );
 
 
1042
 
1043
  $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'id', $guest_author_id );
1044
 
2
 
3
  class Test_Template_Tags extends CoAuthorsPlus_TestCase {
4
 
5
+ use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
6
+
7
  public function setUp() {
8
 
9
  parent::setUp();
13
  * we need CoAuthors_Template_Filters object to check 'the_author' filter.
14
  */
15
  global $coauthors_plus_template_filters;
16
+ $coauthors_plus_template_filters = new CoAuthors_Template_Filters();
17
+
18
+ $this->author1 = $this->factory->user->create_and_get(
19
+ array(
20
+ 'role' => 'author',
21
+ 'user_login' => 'author1',
22
+ )
23
+ );
24
+ $this->editor1 = $this->factory->user->create_and_get(
25
+ array(
26
+ 'role' => 'editor',
27
+ 'user_login' => 'editor1',
28
+ )
29
+ );
30
+
31
+ $this->post = $this->factory->post->create_and_get(
32
+ array(
33
+ 'post_author' => $this->author1->ID,
34
+ 'post_status' => 'publish',
35
+ 'post_content' => rand_str(),
36
+ 'post_title' => rand_str(),
37
+ 'post_type' => 'post',
38
+ )
39
+ );
40
  }
41
 
42
  /**
58
  // Checks for single post author.
59
  $single_cpl = coauthors_posts_links( null, null, null, null, false );
60
 
61
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $single_cpl, 'Author link not found.' );
62
+ $this->assertStringContainsString( $this->author1->display_name, $single_cpl, 'Author name not found.' );
63
 
64
  // Checks for multiple post author.
65
  $coauthors_plus->add_coauthors( $this->post->ID, array( $this->editor1->user_login ), true );
66
 
67
  $multiple_cpl = coauthors_posts_links( null, null, null, null, false );
68
 
69
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $multiple_cpl, 'Main author link not found.' );
70
+ $this->assertStringContainsString( $this->author1->display_name, $multiple_cpl, 'Main author name not found.' );
71
 
72
  // Here we are checking author name should not be more then one time.
73
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
74
  $this->assertEquals( 1, substr_count( $multiple_cpl, ">{$this->author1->display_name}<" ) );
75
+ $this->assertStringContainsString( ' and ', $multiple_cpl, 'Coauthors name separator is not matched.' );
76
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->editor1->ID, $this->editor1->user_nicename ) . '"', $multiple_cpl, 'Coauthor link not found.' );
77
+ $this->assertStringContainsString( $this->editor1->display_name, $multiple_cpl, 'Coauthor name not found.' );
78
 
79
  // Here we are checking editor name should not be more then one time.
80
  // Asserting ">{$this->editor1->display_name}<" because "$this->editor1->display_name" can be multiple times like in href, title, etc.
82
 
83
  $multiple_cpl = coauthors_links( null, ' or ', null, null, false );
84
 
85
+ $this->assertStringContainsString( ' or ', $multiple_cpl, 'Coauthors name separator is not matched.' );
86
+
87
+ $this->assertEquals(
88
+ 10,
89
+ has_filter(
90
+ 'the_author',
91
+ array(
92
+ $coauthors_plus_template_filters,
93
+ 'filter_the_author',
94
+ )
95
+ )
96
+ );
97
 
98
  // Restore backed up post to global.
99
  $GLOBALS['post'] = $post_backup;
125
 
126
  $multiple_cpl = coauthors_links( null, null, null, null, false );
127
 
128
+ $this->assertStringContainsString( $this->author1->display_name, $multiple_cpl, 'Main author name not found.' );
129
  $this->assertEquals( 1, substr_count( $multiple_cpl, $this->author1->display_name ) );
130
+ $this->assertStringContainsString( ' and ', $multiple_cpl, 'Coauthors name separator is not matched.' );
131
+ $this->assertStringContainsString( $this->editor1->display_name, $multiple_cpl, 'Coauthor name not found.' );
132
  $this->assertEquals( 1, substr_count( $multiple_cpl, $this->editor1->display_name ) );
133
 
134
  $multiple_cpl = coauthors_links( null, ' or ', null, null, false );
135
 
136
+ $this->assertStringContainsString( ' or ', $multiple_cpl, 'Coauthors name separator is not matched.' );
137
+
138
+ $this->assertEquals(
139
+ 10,
140
+ has_filter(
141
+ 'the_author',
142
+ array(
143
+ $coauthors_plus_template_filters,
144
+ 'filter_the_author',
145
+ )
146
+ )
147
+ );
148
 
149
  // Restore backed up post to global.
150
  $GLOBALS['post'] = $post_backup;
174
 
175
  // Compare multiple authors.
176
  $coauthors_plus->add_coauthors( $this->post->ID, array( $this->editor1->user_login ), true );
177
+ $this->assertEquals(
178
+ array(
179
+ $this->author1->ID,
180
+ $this->editor1->ID,
181
+ ),
182
+ wp_list_pluck( get_coauthors( $this->post->ID ), 'ID' )
183
+ );
184
  }
185
 
186
  /**
211
  $this->assertEmpty( get_coauthors() );
212
 
213
  $user_id = $this->factory->user->create();
214
+ $post = $this->factory->post->create_and_get(
215
+ array(
216
+ 'post_author' => $user_id,
217
+ )
218
+ );
219
 
220
  $this->assertEquals( array( $user_id ), wp_list_pluck( get_coauthors(), 'ID' ) );
221
 
392
 
393
  $author_link = coauthors_posts_links_single( $this->author1 );
394
 
395
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $author_link, 'Author link not found.' );
396
+ $this->assertStringContainsString( $this->author1->display_name, $author_link, 'Author name not found.' );
397
 
398
  // Here we are checking author name should not be more then one time.
399
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
439
 
440
  // Checking when first name is set for user.
441
  $first_name = 'Test';
442
+ $user_id = $this->factory->user->create(
443
+ array(
444
+ 'first_name' => $first_name,
445
+ )
446
+ );
447
+ $post = $this->factory->post->create_and_get(
448
+ array(
449
+ 'post_author' => $user_id,
450
+ )
451
+ );
452
 
453
  $first_names = coauthors_firstnames( null, null, null, null, false );
454
 
494
 
495
  // Checking when last name is set for user.
496
  $last_name = 'Test';
497
+ $user_id = $this->factory->user->create(
498
+ array(
499
+ 'last_name' => $last_name,
500
+ )
501
+ );
502
+ $post = $this->factory->post->create_and_get(
503
+ array(
504
+ 'post_author' => $user_id,
505
+ )
506
+ );
507
 
508
  $last_names = coauthors_lastnames( null, null, null, null, false );
509
 
549
 
550
  // Checking when nickname is set for user.
551
  $nick_name = 'Test';
552
+ $user_id = $this->factory->user->create(
553
+ array(
554
+ 'nickname' => $nick_name,
555
+ )
556
+ );
557
+ $post = $this->factory->post->create_and_get(
558
+ array(
559
+ 'post_author' => $user_id,
560
+ )
561
+ );
562
 
563
  $nick_names = coauthors_nicknames( null, null, null, null, false );
564
 
602
  $this->assertEquals( '<span>' . $this->author1->user_email . '</span><span>' . $this->editor1->user_email . '</span>', $emails );
603
 
604
  $email = 'test@example.org';
605
+ $user_id = $this->factory->user->create(
606
+ array(
607
+ 'user_email' => $email,
608
+ )
609
+ );
610
+ $post = $this->factory->post->create_and_get(
611
+ array(
612
+ 'post_author' => $user_id,
613
+ )
614
+ );
615
 
616
  $emails = coauthors_emails( null, null, null, null, false );
617
 
637
 
638
  // Backing up global author data.
639
  $authordata_backup = $authordata;
640
+ $authordata = $this->author1;
641
 
642
  // Shows that it's necessary to set $authordata to $this->author1
643
  $this->assertEquals( $authordata, $this->author1, 'Global $authordata not matching expected $this->author1.' );
644
+
645
  $this->author1->type = 'guest-author';
646
 
647
  $this->assertEquals( get_the_author_link(), coauthors_links_single( $this->author1 ), 'Co-Author link generation differs from Core author link one (without user_url)' );
648
+
649
+ wp_update_user(
650
+ array(
651
+ 'ID' => $this->author1->ID,
652
+ 'user_url' => 'example.org',
653
+ )
654
+ );
655
  $authordata = get_userdata( $this->author1->ID ); // Because wp_update_user flushes cache, but does not update global var
656
+
657
  $this->assertEquals( get_the_author_link(), coauthors_links_single( $this->author1 ), 'Co-Author link generation differs from Core author link one (with user_url)' );
658
 
659
  $author_link = coauthors_links_single( $this->author1 );
660
+ $this->assertStringContainsString( get_the_author_meta( 'url' ), $author_link, 'Author url not found in link.' );
661
+ $this->assertStringContainsString( get_the_author(), $author_link, 'Author name not found in link.' );
662
 
663
  // Here we are checking author name should not be more then one time.
664
  // Asserting ">get_the_author()<" because "get_the_author()" can be multiple times like in href, title, etc.
688
  // Backing up global author data.
689
  $authordata_backup = $authordata;
690
 
691
+ $user_id = $this->factory->user->create(
692
+ array(
693
+ 'user_url' => 'example.org',
694
+ )
695
+ );
696
  $user = get_user_by( 'id', $user_id );
697
 
698
  $authordata = $user;
699
  $author_link = coauthors_links_single( $user );
700
 
701
+ $this->assertStringContainsString( get_the_author_meta( 'url' ), $author_link, 'Author link not found.' );
702
+ $this->assertStringContainsString( get_the_author(), $author_link, 'Author name not found.' );
703
 
704
  // Here we are checking author name should not be more then one time.
705
  // Asserting ">get_the_author()<" because "get_the_author()" can be multiple times like in href, title, etc.
826
 
827
  $coauthors = coauthors_wp_list_authors( $args );
828
 
829
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $coauthors, 'Author link not found.' );
830
+ $this->assertStringContainsString( $this->author1->display_name, $coauthors, 'Author name not found.' );
831
 
832
  $coauthors = coauthors_wp_list_authors( $args );
833
 
838
 
839
  $coauthors = coauthors_wp_list_authors( $args );
840
 
841
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->author1->ID, $this->author1->user_nicename ) . '"', $coauthors, 'Main author link not found.' );
842
+ $this->assertStringContainsString( $this->author1->display_name, $coauthors, 'Main author name not found.' );
843
 
844
  // Here we are checking author name should not be more then one time.
845
  // Asserting ">{$this->author1->display_name}<" because "$this->author1->display_name" can be multiple times like in href, title, etc.
846
  $this->assertEquals( 1, substr_count( $coauthors, ">{$this->author1->display_name}<" ) );
847
 
848
+ $this->assertStringContainsString( '</li><li>', $coauthors, 'Coauthors name separator is not matched.' );
849
+ $this->assertStringContainsString( 'href="' . get_author_posts_url( $this->editor1->ID, $this->editor1->user_nicename ) . '"', $coauthors, 'Coauthor link not found.' );
850
+ $this->assertStringContainsString( $this->editor1->display_name, $coauthors, 'Coauthor name not found.' );
851
 
852
  // Here we are checking editor name should not be more then one time.
853
  // Asserting ">{$this->editor1->display_name}<" because "$this->editor1->display_name" can be multiple times like in href, title, etc.
861
  */
862
  public function test_coauthors_wp_list_authors_for_optioncount() {
863
 
864
+ $this->assertStringContainsString(
865
+ '(' . count_user_posts( $this->author1->ID ) . ')',
866
+ coauthors_wp_list_authors(
867
+ array(
868
+ 'echo' => false,
869
+ 'optioncount' => true,
870
+ )
871
+ )
872
+ );
873
  }
874
 
875
  /**
884
  'show_fullname' => true,
885
  );
886
 
887
+ $this->assertStringContainsString( $this->author1->display_name, coauthors_wp_list_authors( $args ) );
888
 
889
+ $user = $this->factory->user->create_and_get(
890
+ array(
891
+ 'first_name' => 'First',
892
+ 'last_name' => 'Last',
893
+ )
894
+ );
895
 
896
+ $this->factory->post->create(
897
+ array(
898
+ 'post_author' => $user->ID,
899
+ )
900
+ );
901
 
902
+ $this->assertStringContainsString( "{$user->user_firstname} {$user->user_lastname}", coauthors_wp_list_authors( $args ) );
903
  }
904
 
905
  /**
911
 
912
  global $coauthors_plus;
913
 
914
+ $coauthors_plus->guest_authors->create(
915
+ array(
916
+ 'user_login' => 'author2',
917
+ 'display_name' => 'author2',
918
+ )
919
+ );
920
 
921
+ $this->assertStringContainsString(
922
+ 'author2',
923
+ coauthors_wp_list_authors(
924
+ array(
925
+ 'echo' => false,
926
+ 'hide_empty' => false,
927
+ )
928
+ )
929
+ );
930
  }
931
 
932
  /**
937
  public function test_coauthors_wp_list_authors_for_feed() {
938
 
939
  $feed_text = 'link to feed';
940
+ $coauthors = coauthors_wp_list_authors(
941
+ array(
942
+ 'echo' => false,
943
+ 'feed' => $feed_text,
944
+ )
945
+ );
946
 
947
+ $this->assertStringContainsString( esc_url( get_author_feed_link( $this->author1->ID ) ), $coauthors );
948
+ $this->assertStringContainsString( $feed_text, $coauthors );
949
  }
950
 
951
  /**
956
  public function test_coauthors_wp_list_authors_for_feed_image() {
957
 
958
  $feed_image = WP_TESTS_DOMAIN . '/path/to/a/graphic.png';
959
+ $coauthors = coauthors_wp_list_authors(
960
+ array(
961
+ 'echo' => false,
962
+ 'feed_image' => $feed_image,
963
+ )
964
+ );
965
 
966
+ $this->assertStringContainsString( esc_url( get_author_feed_link( $this->author1->ID ) ), $coauthors );
967
+ $this->assertStringContainsString( $feed_image, $coauthors );
968
  }
969
 
970
  /**
976
 
977
  $feed_type = 'atom';
978
  $feed_text = 'link to feed';
979
+ $coauthors = coauthors_wp_list_authors(
980
+ array(
981
+ 'echo' => false,
982
+ 'feed_type' => $feed_type,
983
+ 'feed' => $feed_text,
984
+ )
985
+ );
986
+
987
+ $this->assertStringContainsString( esc_url( get_author_feed_link( $this->author1->ID, $feed_type ) ), $coauthors );
988
+ $this->assertStringContainsString( $feed_type, $coauthors );
989
+ $this->assertStringContainsString( $feed_text, $coauthors );
990
  }
991
 
992
  /**
996
  */
997
  public function test_coauthors_wp_list_authors_for_style() {
998
 
999
+ $coauthors = coauthors_wp_list_authors(
1000
+ array(
1001
+ 'echo' => false,
1002
+ 'style' => 'none',
1003
+ )
1004
+ );
1005
 
1006
  $this->assertNotContains( '<li>', $coauthors );
1007
  $this->assertNotContains( '</li>', $coauthors );
1044
 
1045
  $this->assertEmpty( coauthors_wp_list_authors( $args ) );
1046
 
1047
+ $guest_author_id = $coauthors_plus->guest_authors->create(
1048
+ array(
1049
+ 'user_login' => 'author2',
1050
+ 'display_name' => 'author2',
1051
+ )
1052
+ );
1053
 
1054
  $this->assertEmpty( coauthors_wp_list_authors( $args ) );
1055
 
1057
 
1058
  $coauthors_plus->add_coauthors( $this->post->ID, array( $guest_author->user_login ), true );
1059
 
1060
+ $this->assertStringContainsString( $guest_author->display_name, coauthors_wp_list_authors( $args ) );
1061
  }
1062
 
1063
  /**
1068
  public function test_coauthors_get_avatar_default() {
1069
 
1070
  $this->assertEmpty( coauthors_get_avatar( $this->author1->ID ) );
1071
+
1072
  $this->assertEquals( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*'( loading='[^']*')?/>$|", coauthors_get_avatar( $this->author1 ) ), 1 );
1073
  }
1074
 
1081
 
1082
  global $coauthors_plus;
1083
 
1084
+ $guest_author_id = $coauthors_plus->guest_authors->create(
1085
+ array(
1086
+ 'user_login' => 'author2',
1087
+ 'display_name' => 'author2',
1088
+ )
1089
+ );
1090
 
1091
  $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'id', $guest_author_id );
1092
+ $attachment_id = $this->factory->attachment->create_upload_object( __DIR__ . '/fixtures/dummy-attachment.png', $guest_author_id );
1093
 
1094
  $this->assertEquals( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*'( loading='[^']*')?/>$|", coauthors_get_avatar( $guest_author ) ), 1 );
1095
 
 
 
 
 
 
 
 
 
1096
  set_post_thumbnail( $guest_author->ID, $attachment_id );
1097
 
1098
  $avatar = coauthors_get_avatar( $guest_author );
1099
  $attachment_url = wp_get_attachment_url( $attachment_id );
1100
 
1101
+ // Checking for dummy-attachment instead of dummy-attachment.png, as filename might change to
1102
+ // dummy-attachment-1.png, dummy-attachment-2.png, etc. when running multiple tests.
1103
+ $this->assertStringContainsString( 'dummy-attachment', $avatar );
1104
+ $this->assertStringContainsString( $attachment_url, $avatar );
1105
  }
1106
 
1107
  /**
1113
 
1114
  global $coauthors_plus;
1115
 
1116
+ $guest_author_id = $coauthors_plus->guest_authors->create(
1117
+ array(
1118
+ 'user_login' => 'author2',
1119
+ 'display_name' => 'author2',
1120
+ )
1121
+ );
1122
 
1123
  $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'id', $guest_author_id );
1124
 
upgrade.php CHANGED
@@ -15,9 +15,13 @@ function coauthors_plus_upgrade_20() {
15
  global $coauthors_plus;
16
 
17
  // Get all posts with meta_key _coauthor
18
- $all_posts = get_posts( array( 'numberposts' => '-1', 'meta_key' => '_coauthor' ) );
 
 
 
 
 
19
 
20
-
21
  foreach ( $all_posts as $single_post ) {
22
  // reset execution time limit
23
  set_time_limit( 60 );
15
  global $coauthors_plus;
16
 
17
  // Get all posts with meta_key _coauthor
18
+ $all_posts = get_posts(
19
+ array(
20
+ 'numberposts' => '-1',
21
+ 'meta_key' => '_coauthor',
22
+ )
23
+ );
24
 
 
25
  foreach ( $all_posts as $single_post ) {
26
  // reset execution time limit
27
  set_time_limit( 60 );