Make WordPress Core

Opened 15 years ago

Closed 11 years ago

Last modified 11 years ago

#11003 closed defect (bug) (fixed)

wp_get_object_terms Returns Duplicate Terms

Reported by: filosofo's profile filosofo Owned by: ryan's profile ryan
Milestone: 4.0 Priority: normal
Severity: normal Version: 2.9
Component: Taxonomy Keywords: has-patch
Focuses: Cc:

Description

wp_get_object_terms() accepts multiple objects in its first parameter. If the multiple objects have terms in common, then wp_get_object_terms() returns those terms more than once in the returned array of term data.

Patch makes the array of terms unique.

Attachments (4)

wp_get_object_terms-unique-results.11003.diff (859 bytes) - added by filosofo 15 years ago.
11003.diff (1.7 KB) - added by dd32 15 years ago.
11003.patch (2.4 KB) - added by hakre 15 years ago.
11003.notice.patch (494 bytes) - added by scribu 15 years ago.

Download all attachments as: .zip

Change History (21)

#1 @dd32
15 years ago

Any chance of this in for 2.9?

#2 @dd32
15 years ago

By default, array_unique() compares the contents of the array as a string, fouls it up as you found out..

Did setting the compare to REGULAR help at all? ie. $terms = array_unique($terms, SORT_REGULAR);

#3 @dd32
15 years ago

The attached patch has a slight issue, {{fields = all_with_object_id}}} will no longer return a the full set of object Id/term id/taxonomy id suite, only the first termid found for each..

Simply adding DISTINCT to the queries seems a better option to me.. More foolproof to let the SQL layer filter out the other rows. see patch.

@dd32
15 years ago

#4 @dd32
15 years ago

  • Keywords tested commit removed

I've tested the patch very basic, And seems to work in all the cases i can think of.

#5 @dd32
15 years ago

Before:

$terms = wp_get_object_terms( array(10,12), 'category', array('fields' => 'all_with_object_id') );

var_dump($terms);

array(2) {
  [0]=>
  object(stdClass)#10 (10) {
    ["term_id"]=>
    string(1) "4"
    ["name"]=>
    string(6) "Artist"
    ["slug"]=>
    string(6) "artist"
    ["term_group"]=>
    string(1) "0"
    ["term_taxonomy_id"]=>
    string(1) "4"
    ["taxonomy"]=>
    string(8) "category"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    string(1) "0"
    ["count"]=>
    string(1) "2"
    ["object_id"]=>
    string(2) "10"
  }
  [1]=>
  object(stdClass)#9 (10) {
    ["term_id"]=>
    string(1) "4"
    ["name"]=>
    string(6) "Artist"
    ["slug"]=>
    string(6) "artist"
    ["term_group"]=>
    string(1) "0"
    ["term_taxonomy_id"]=>
    string(1) "4"
    ["taxonomy"]=>
    string(8) "category"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    string(1) "0"
    ["count"]=>
    string(1) "2"
    ["object_id"]=>
    string(2) "12"
  }
}

Note, Object ID in there.

With wp_get_object_terms-unique-results.11003.diff:

$terms = wp_get_object_terms( array(10,12), 'category', array('fields' => 'all_with_object_id') );

var_dump($terms);
 
array(1) {
  [4]=>
  object(stdClass)#9 (10) {
    ["term_id"]=>
    string(1) "4"
    ["name"]=>
    string(6) "Artist"
    ["slug"]=>
    string(6) "artist"
    ["term_group"]=>
    string(1) "0"
    ["term_taxonomy_id"]=>
    string(1) "4"
    ["taxonomy"]=>
    string(8) "category"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    string(1) "0"
    ["count"]=>
    string(1) "2"
    ["object_id"]=>
    string(2) "12"
  }
}

Note, that due to the indexing of the array on $term->term_id in order to filter out duplicates, the 2 have been combined.

@hakre
15 years ago

#6 @hakre
15 years ago

  • Keywords dev-feedback added

It might make sense to have that optional to not change the current behaviour (back-compat), for example I might want to have that dupes instead of not.

In my patch I adopted the premier suggestion and added an additional parameter: select. It might make sense to adopt that to the SQL queries as well.

#7 @ryan
15 years ago

  • Milestone changed from 3.0 to 3.1

#8 @kevinB
15 years ago

  • Cc kevinB added

#9 @scribu
15 years ago

  • Cc scribu added
  • Keywords changed from has-patch, dev-feedback to has-patch dev-feedback

#10 @scribu
15 years ago

It's pretty easy to make the terms unique afterwards, once you know there might be duplicates.

Maybe we should just add a notice in the documentation?

#11 @filosofo
15 years ago

It's better than nothing, but not a true solution.

#12 @scribu
15 years ago

How about this: use DISTINCT to remove duplicate terms, but only when $fields != 'all_with_object_id'.

#13 @nacin
14 years ago

  • Milestone changed from Awaiting Triage to Future Release

#14 @mikeschinkel
14 years ago

  • Cc mikeschinkel@… added

Related superset of this ticket: ##15675

#15 @wonderboymusic
11 years ago

  • Keywords dev-feedback removed
  • Milestone changed from Future Release to 4.0

Since we are trying to filter by uniqueness, the dupes that have different values for object_id are not really dupes, and they only appear when 'all_with_object_id' is passed.

$terms = array_values( array_unique( $terms, SORT_REGULAR ) ); pre-filter works for both solutions described above.

#16 @wonderboymusic
11 years ago

  • Resolution set to fixed
  • Status changed from new to closed

In 28583:

In wp_get_object_terms(), before returning terms (and before running them through the 'wp_get_object_terms' filter) - run them through $terms = array_values( array_unique( $terms, SORT_REGULAR ) ).

There will be "dupes" when the function is called with 'fields' => 'all_with_object_id', but the objects will actually be unique due to the object_id addition, so they shouldn't be filtered out.

Adds unit tests. All other unit tests pass.

Fixes #11003.

#17 @jorbin
11 years ago

array_unique is used with the second optional parameter of STRING_REGULAR which was added in php 5.2.9. Our minimum requirements are 5.2.4. This will trigger Warning: Wrong parameter count for array_unique() and cause array_unique to return NULL

http://www.php.net/manual/en/function.array-unique.php

Note: See TracTickets for help on using tickets.