Open manuelRod opened 5 months ago
Regular posts also doesn't respect the sorting option from post editing screen (gutenberg + hybrid theme)
@bystrzan While I was debugging this issue, I noticed that the AJAX call made in the post editor also uses add_coauthors. Meaning, as you mentioned, sometimes the order won't be respected also using the plugin itself.
@manuelRod by any chance, do you still see the same thing happening if you used this PR?
The issue stems from WordPress Core function wp_set_object_terms
and as an extension, wp_set_post_term
don not maintain order of the input array terms. This is especially apparent when the input array of terms include terms that were already added previously.
Co-Authors Plus does have its own ordering mechanism but that does not work when adding terms that don't already exist for a particular post programatically / via CLI. The ordering does work when the Post Editor interface is used. The command does fix the ordering on a second run since all the authors required for a post already exist (even if they were in the wrong order after the first run).
wp_set_post_terms
eventually calls wp_set_object_terms
.
function wp_set_post_terms( $post_id = 0, $terms = '', $taxonomy = 'post_tag', $append = false ) {
$post_id = (int) $post_id;
// CODE TRUNCATED FOR READABILITY
return wp_set_object_terms( $post_id, $terms, $taxonomy, $append );
}
References:
wp_set_post_term
: https://github.com/WordPress/WordPress/blob/ad3c5a4946cc39fa68350f0e15306da737dd38b0/wp-includes/post.php#L5435wp_set_object_terms
: https://github.com/WordPress/WordPress/blob/aeb9f372381cf7952973a66241aa179db083866f/wp-includes/taxonomy.php#L2798So as a proof of concept, I booted up a WordPress instance using Local (https://localwp.com/).
I activated Twenty-Twenty Two theme, and added the following code snippet in that theme's functions.php:
wp_set_post_terms( 19, array('test'), 'post_tag');
// 19 is just the post ID of a post
// array('test') is a term
// `post_tag` is the taxonomy I am adding that term to for Post ID: 19
Once I added that, I dumped the output as follows:
var_dump( wp_get_post_terms( 19, 'post_tag' ) );
// OUTPUT
array(1) {
[0]=>
object(WP_Term)#1672 (10) {
["term_id"]=>
int(3182)
["name"]=>
string(4) "test"
["slug"]=>
string(4) "test"
["term_group"]=>
int(0)
["term_taxonomy_id"]=>
int(3182)
["taxonomy"]=>
string(8) "post_tag"
["description"]=>
string(0) ""
["parent"]=>
int(0)
["count"]=>
int(1)
["filter"]=>
string(3) "raw"
}
}
I then modified the wp_set_post_terms line to:
wp_set_object_terms( 19, array( 'test', 'john-doe'), 'post_tag' );
// I am still passing `test` as first entry
However, now when I dump the terms for this post:
var_dump( wp_get_post_terms( 19, 'post_tag' ) );
// OUTPUT
array(2) {
[0]=>
object(WP_Term)#1674 (10) {
["term_id"]=>
int(3183)
["name"]=>
string(8) "john-doe"
["slug"]=>
string(8) "john-doe"
["term_group"]=>
int(0)
["term_taxonomy_id"]=>
int(3183)
["taxonomy"]=>
string(8) "post_tag"
["description"]=>
string(0) ""
["parent"]=>
int(0)
["count"]=>
int(1)
["filter"]=>
string(3) "raw"
}
[1]=>
object(WP_Term)#1675 (10) {
["term_id"]=>
int(3182)
["name"]=>
string(4) "test"
["slug"]=>
string(4) "test"
["term_group"]=>
int(0)
["term_taxonomy_id"]=>
int(3182)
["taxonomy"]=>
string(8) "post_tag"
["description"]=>
string(0) ""
["parent"]=>
int(0)
["count"]=>
int(1)
["filter"]=>
string(3) "raw"
}
}
The already existing term from the array test is NOT first even though I explicitly mentioned test as the first entry.
So that means wp_set_post_terms
DOES NOT preserve the order of the input array passed to it.
Co-Authors Plus has an additional field that it uses to maintain order AFTER the terms are added. This column term_order already ships with WordPress Core as part of the wp_term_relationships
table. This is the table that maps OBJECT IDs (which are Post IDs for this example) to TERM TAXONOMY IDs (which are Author Term IDs for this example) and has a column named term_order. This column is NOT USED BY DEFAULT in get_the_terms()
etc.
WordPress Core Database Description: https://codex.wordpress.org/Database_Description
The issue stems from wp_set_object_terms
not allowing you to set an order when assigning terms to a post. The term_order
is never touched during assignment of a term to a post.
This is how WordPress Core does it, and it does make logical sense, as one cannot know the custom order of a term in isolation during an insert, and the sort will fallback to being alphabetical or by term_id
.
Any custom ordering step, if needed, has to be an additional step AFTER the terms are assigned to a post.
**Co-Authors Plus does not cause order mismatch when using the ordering interface on the Post Editor pages, since order is passed via the custom metabox, which is presumably hooked into other actions preserving the order, presumably using the save_post
action.
In the context of your custom command, however, Co-Authors Plus abides by how WordPress Core allows it to set terms, which is without any order, and requires an additional step AFTER the terms are assigned for re-ordering, since there are no metaboxes or save_post
action to hook into.**
When using the method $coauthors_plus->add_coauthors()
, add a verification step that checks whether the order of coauthor terms is the same as the source you are importing it from, and if there is an order mismatch, re-add the same array of authors again.
I am currently exploring the possibility of integrating order verification into the Co-Authors Plus plugin. This process may take some time as I need to familiarize myself with the project's codebase to determine the feasibility and optimal placement of this feature.
Should this integration prove feasible, I will submit a pull request and provide a link to it in this thread.
Hello,
We are currently migrating from another custom system to co-authors. We are having a lot of trouble with the migration since the ordering of authors seems to be completely random. Sometimes (most of the time) respects the old order, but sometimes it doesn't. Maybe the way we are doing it it's wrong (?)
How are we doing it? Passing an array of authors (with user_nicename) to add_coauthors function.
Sometimes we will get co-authors in the right other, sometimes inverse.
Why the order is sometimes not respected? I tried other combinations, like calling add_coauthors with just one author, n times. Nothing seems to work, and all the time seems random.
Any clues? Are we doing it wrong?
Thanks,