query.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. <?php
  2. /**
  3. * @group taxonomy
  4. */
  5. class Tests_Term_Query extends WP_UnitTestCase {
  6. /**
  7. * @ticket 37545
  8. */
  9. public function test_taxonomy_should_accept_single_taxonomy_as_string() {
  10. register_taxonomy( 'wptests_tax_1', 'post' );
  11. register_taxonomy( 'wptests_tax_2', 'post' );
  12. $term_1 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  13. $term_2 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_2' ) );
  14. $q = new WP_Term_Query(
  15. array(
  16. 'taxonomy' => 'wptests_tax_2',
  17. 'fields' => 'ids',
  18. 'hide_empty' => false,
  19. )
  20. );
  21. $this->assertSameSets( array( $term_2 ), $q->terms );
  22. }
  23. public function test_taxonomy_should_accept_taxonomy_array() {
  24. register_taxonomy( 'wptests_tax_1', 'post' );
  25. register_taxonomy( 'wptests_tax_2', 'post' );
  26. $term_1 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  27. $term_2 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_2' ) );
  28. $q = new WP_Term_Query(
  29. array(
  30. 'taxonomy' => array( 'wptests_tax_2' ),
  31. 'fields' => 'ids',
  32. 'hide_empty' => false,
  33. )
  34. );
  35. $this->assertSameSets( array( $term_2 ), $q->terms );
  36. }
  37. /**
  38. * @ticket 37074
  39. */
  40. public function test_term_taxonomy_id_single() {
  41. global $wpdb;
  42. register_taxonomy( 'wptests_tax', 'post' );
  43. $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
  44. // Manually change the term_taxonomy_id to something else.
  45. $wpdb->update(
  46. $wpdb->term_taxonomy,
  47. array( 'term_taxonomy_id' => 12345 ),
  48. array( 'term_id' => $terms[0] )
  49. );
  50. $q = new WP_Term_Query(
  51. array(
  52. 'term_taxonomy_id' => 12345,
  53. 'fields' => 'ids',
  54. 'hide_empty' => false,
  55. )
  56. );
  57. $this->assertSameSets( array( $terms[0] ), $q->terms );
  58. }
  59. /**
  60. * @ticket 37074
  61. */
  62. public function test_term_taxonomy_id_array() {
  63. global $wpdb;
  64. register_taxonomy( 'wptests_tax', 'post' );
  65. $terms = self::factory()->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
  66. // Manually change the term_taxonomy_id to something else.
  67. $wpdb->update(
  68. $wpdb->term_taxonomy,
  69. array( 'term_taxonomy_id' => 12345 ),
  70. array( 'term_id' => $terms[0] )
  71. );
  72. $wpdb->update(
  73. $wpdb->term_taxonomy,
  74. array( 'term_taxonomy_id' => 6789 ),
  75. array( 'term_id' => $terms[2] )
  76. );
  77. $q = new WP_Term_Query(
  78. array(
  79. 'term_taxonomy_id' => array( 12345, 6789 ),
  80. 'fields' => 'ids',
  81. 'hide_empty' => false,
  82. )
  83. );
  84. $this->assertSameSets( array( $terms[0], $terms[2] ), $q->terms );
  85. }
  86. /**
  87. * @ticket 37151
  88. */
  89. public function test_order_by_meta_value_num() {
  90. register_taxonomy( 'wptests_tax', 'post' );
  91. $terms = self::factory()->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
  92. add_term_meta( $terms[0], 'foo', 10 );
  93. add_term_meta( $terms[1], 'foo', 1 );
  94. add_term_meta( $terms[2], 'foo', 100 );
  95. $q = new WP_Term_Query(
  96. array(
  97. 'taxonomy' => array( 'wptests_tax' ),
  98. 'fields' => 'ids',
  99. 'hide_empty' => false,
  100. 'meta_key' => 'foo',
  101. 'orderby' => 'meta_value_num',
  102. )
  103. );
  104. $found = array_map( 'intval', $q->terms );
  105. $this->assertSame( array( $terms[1], $terms[0], $terms[2] ), $found );
  106. }
  107. /**
  108. * @ticket 37378
  109. */
  110. public function test_order_by_keyword_should_not_be_duplicated_when_filtered() {
  111. register_taxonomy( 'wptests_tax', 'post' );
  112. add_filter( 'terms_clauses', array( $this, 'filter_terms_clauses' ) );
  113. $q = new WP_Term_Query(
  114. array(
  115. 'taxonomy' => array( 'wptests_tax' ),
  116. 'orderby' => 'name',
  117. )
  118. );
  119. remove_filter( 'terms_clauses', array( $this, 'filter_terms_clauses' ) );
  120. $this->assertContains( 'ORDER BY tt.term_id', $q->request );
  121. $this->assertNotContains( 'ORDER BY ORDER BY', $q->request );
  122. }
  123. public function filter_terms_clauses( $clauses ) {
  124. $clauses['orderby'] = 'ORDER BY tt.term_id';
  125. return $clauses;
  126. }
  127. /**
  128. * @ticket 37198
  129. */
  130. public function test_order_by_term_order_should_fall_back_on_term_id_when_relationship_table_is_not_being_joined() {
  131. register_taxonomy( 'wptests_tax', 'post' );
  132. $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
  133. sort( $terms );
  134. $q = new WP_Term_Query(
  135. array(
  136. 'taxonomy' => 'wptests_tax',
  137. 'orderby' => 'term_order',
  138. 'fields' => 'ids',
  139. 'hide_empty' => false,
  140. )
  141. );
  142. $this->assertSame( $terms, $q->get_terms() );
  143. }
  144. /**
  145. * @ticket 37591
  146. */
  147. public function test_terms_is_set() {
  148. register_taxonomy( 'wptests_tax_1', 'post' );
  149. self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  150. $q1 = new WP_Term_Query(
  151. array(
  152. 'taxonomy' => 'wptests_tax_1',
  153. 'hide_empty' => false,
  154. )
  155. );
  156. $this->assertNotEmpty( $q1->terms );
  157. $q2 = new WP_Term_Query(
  158. array(
  159. 'taxonomy' => 'wptests_tax_1',
  160. 'hide_empty' => false,
  161. )
  162. );
  163. $this->assertNotEmpty( $q2->terms );
  164. }
  165. /**
  166. * @ticket 23261
  167. * @ticket 37904
  168. */
  169. public function test_orderby_include_with_comma_separated_list() {
  170. register_taxonomy( 'wptests_tax_1', 'post' );
  171. $t1 = self::factory()->term->create_and_get( array( 'taxonomy' => 'wptests_tax_1' ) );
  172. $t2 = self::factory()->term->create_and_get( array( 'taxonomy' => 'wptests_tax_1' ) );
  173. $query = new WP_Term_Query(
  174. array(
  175. 'include' => "{$t1->term_id},{$t2->term_id}",
  176. 'orderby' => 'include',
  177. 'hide_empty' => false,
  178. )
  179. );
  180. $terms = $query->get_terms();
  181. $this->assertEquals( array( $t1, $t2 ), $terms );
  182. }
  183. /**
  184. * @ticket 37198
  185. */
  186. public function test_object_ids_single() {
  187. register_taxonomy( 'wptests_tax_1', 'post' );
  188. $p = self::factory()->post->create();
  189. $t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  190. wp_set_object_terms( $p, array( $t ), 'wptests_tax_1' );
  191. $query = new WP_Term_Query(
  192. array(
  193. 'taxonomy' => 'wptests_tax_1',
  194. 'object_ids' => $p,
  195. 'fields' => 'ids',
  196. )
  197. );
  198. $this->assertSameSets( array( $t ), $query->terms );
  199. }
  200. /**
  201. * @ticket 37198
  202. */
  203. public function test_object_ids_array() {
  204. register_taxonomy( 'wptests_tax_1', 'post' );
  205. $p = self::factory()->post->create();
  206. $t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  207. wp_set_object_terms( $p, array( $t ), 'wptests_tax_1' );
  208. $query = new WP_Term_Query(
  209. array(
  210. 'taxonomy' => 'wptests_tax_1',
  211. 'object_ids' => array( $p ),
  212. 'fields' => 'ids',
  213. )
  214. );
  215. $this->assertSameSets( array( $t ), $query->terms );
  216. }
  217. /**
  218. * @ticket 37198
  219. */
  220. public function test_duplicates_should_be_removed_for_fields_all() {
  221. register_taxonomy( 'wptests_tax_1', 'post' );
  222. $posts = self::factory()->post->create_many( 2 );
  223. $t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  224. foreach ( $posts as $p ) {
  225. wp_set_object_terms( $p, array( $t ), 'wptests_tax_1' );
  226. }
  227. $query = new WP_Term_Query(
  228. array(
  229. 'taxonomy' => 'wptests_tax_1',
  230. 'object_ids' => $posts,
  231. 'fields' => 'all',
  232. )
  233. );
  234. $this->assertSame( 1, count( $query->terms ) );
  235. $this->assertSame( $t, reset( $query->terms )->term_id );
  236. }
  237. /**
  238. * @ticket 37198
  239. */
  240. public function test_duplicates_should_not_be_removed_for_fields_all_with_object_id() {
  241. register_taxonomy( 'wptests_tax_1', 'post' );
  242. $posts = self::factory()->post->create_many( 2 );
  243. $t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  244. foreach ( $posts as $p ) {
  245. wp_set_object_terms( $p, array( $t ), 'wptests_tax_1' );
  246. }
  247. $query = new WP_Term_Query(
  248. array(
  249. 'taxonomy' => 'wptests_tax_1',
  250. 'object_ids' => $posts,
  251. 'fields' => 'all_with_object_id',
  252. )
  253. );
  254. $this->assertSame( 2, count( $query->terms ) );
  255. foreach ( $query->terms as $term ) {
  256. $this->assertSame( $t, $term->term_id );
  257. }
  258. }
  259. /**
  260. * @ticket 44221
  261. */
  262. public function test_all_with_object_id_should_return_term_objects() {
  263. register_taxonomy( 'wptests_tax_1', 'post' );
  264. $posts = self::factory()->post->create_many( 2 );
  265. $t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_1' ) );
  266. foreach ( $posts as $p ) {
  267. wp_set_object_terms( $p, array( $t ), 'wptests_tax_1' );
  268. }
  269. $query = new WP_Term_Query();
  270. $args = array(
  271. 'taxonomy' => 'wptests_tax_1',
  272. 'object_ids' => $posts,
  273. 'fields' => 'all_with_object_id',
  274. );
  275. $terms = $query->query( $args );
  276. $this->assertNotEmpty( $terms );
  277. foreach ( $terms as $term ) {
  278. $this->assertInstanceOf( 'WP_Term', $term );
  279. $this->assertObjectHasAttribute( 'object_id', $term );
  280. }
  281. // Run again to check the cached response.
  282. $terms = $query->query( $args );
  283. $this->assertNotEmpty( $terms );
  284. foreach ( $terms as $term ) {
  285. $this->assertInstanceOf( 'WP_Term', $term );
  286. $this->assertObjectHasAttribute( 'object_id', $term );
  287. }
  288. }
  289. /**
  290. * @ticket 37198
  291. * @group cache
  292. */
  293. public function test_object_ids_cache_should_be_invalidated_by_term_relationship_change() {
  294. register_taxonomy( 'wptests_tax_1', 'post' );
  295. $p = self::factory()->post->create();
  296. $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax_1' ) );
  297. wp_set_object_terms( $p, array( $terms[0] ), 'wptests_tax_1' );
  298. $query = new WP_Term_Query(
  299. array(
  300. 'taxonomy' => 'wptests_tax_1',
  301. 'object_ids' => $p,
  302. 'fields' => 'ids',
  303. )
  304. );
  305. $found = $query->get_terms();
  306. $this->assertSameSets( array( $terms[0] ), $found );
  307. wp_set_object_terms( $p, array( $terms[1] ), 'wptests_tax_1' );
  308. $query = new WP_Term_Query(
  309. array(
  310. 'taxonomy' => 'wptests_tax_1',
  311. 'object_ids' => $p,
  312. 'fields' => 'ids',
  313. )
  314. );
  315. $found = $query->get_terms();
  316. $this->assertSameSets( array( $terms[1] ), $found );
  317. }
  318. /**
  319. * @ticket 38295
  320. * @group cache
  321. */
  322. public function test_count_query_should_be_cached() {
  323. global $wpdb;
  324. register_taxonomy( 'wptests_tax_1', 'post' );
  325. $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax_1' ) );
  326. $query = new WP_Term_Query(
  327. array(
  328. 'taxonomy' => 'wptests_tax_1',
  329. 'fields' => 'count',
  330. 'hide_empty' => false,
  331. )
  332. );
  333. $count = $query->get_terms();
  334. $this->assertEquals( 2, $count );
  335. $num_queries = $wpdb->num_queries;
  336. $query = new WP_Term_Query(
  337. array(
  338. 'taxonomy' => 'wptests_tax_1',
  339. 'fields' => 'count',
  340. 'hide_empty' => false,
  341. )
  342. );
  343. $count = $query->get_terms();
  344. $this->assertEquals( 2, $count );
  345. $this->assertSame( $num_queries, $wpdb->num_queries );
  346. }
  347. /**
  348. * @ticket 38295
  349. * @group cache
  350. */
  351. public function test_count_query_cache_should_be_invalidated_with_incrementor_bump() {
  352. register_taxonomy( 'wptests_tax_1', 'post' );
  353. $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax_1' ) );
  354. $query = new WP_Term_Query(
  355. array(
  356. 'taxonomy' => 'wptests_tax_1',
  357. 'fields' => 'count',
  358. 'hide_empty' => false,
  359. )
  360. );
  361. $count = $query->get_terms();
  362. $this->assertEquals( 2, $count );
  363. wp_delete_term( $terms[0], 'wptests_tax_1' );
  364. $query = new WP_Term_Query(
  365. array(
  366. 'taxonomy' => 'wptests_tax_1',
  367. 'fields' => 'count',
  368. 'hide_empty' => false,
  369. )
  370. );
  371. $count = $query->get_terms();
  372. $this->assertEquals( 1, $count );
  373. }
  374. /**
  375. * @ticket 40496
  376. */
  377. public function test_get_the_terms_should_respect_taxonomy_orderby() {
  378. register_taxonomy(
  379. 'wptests_tax',
  380. 'post',
  381. array(
  382. 'sort' => true,
  383. 'args' => array(
  384. 'orderby' => 'term_order',
  385. ),
  386. )
  387. );
  388. $term_ids = self::factory()->term->create_many(
  389. 2,
  390. array(
  391. 'taxonomy' => 'wptests_tax',
  392. )
  393. );
  394. $post_id = self::factory()->post->create();
  395. wp_set_object_terms( $post_id, array( $term_ids[0], $term_ids[1] ), 'wptests_tax' );
  396. $terms = get_the_terms( $post_id, 'wptests_tax' );
  397. $this->assertSame( array( $term_ids[0], $term_ids[1] ), wp_list_pluck( $terms, 'term_id' ) );
  398. // Flip the order.
  399. wp_set_object_terms( $post_id, array( $term_ids[1], $term_ids[0] ), 'wptests_tax' );
  400. $terms = get_the_terms( $post_id, 'wptests_tax' );
  401. $this->assertSame( array( $term_ids[1], $term_ids[0] ), wp_list_pluck( $terms, 'term_id' ) );
  402. }
  403. /**
  404. * @ticket 40496
  405. */
  406. public function test_wp_get_object_terms_should_respect_taxonomy_orderby() {
  407. register_taxonomy(
  408. 'wptests_tax',
  409. 'post',
  410. array(
  411. 'sort' => true,
  412. 'args' => array(
  413. 'orderby' => 'term_order',
  414. ),
  415. )
  416. );
  417. $term_ids = self::factory()->term->create_many(
  418. 2,
  419. array(
  420. 'taxonomy' => 'wptests_tax',
  421. )
  422. );
  423. $post_id = self::factory()->post->create();
  424. wp_set_object_terms( $post_id, array( $term_ids[0], $term_ids[1] ), 'wptests_tax' );
  425. $terms = wp_get_object_terms( $post_id, array( 'category', 'wptests_tax' ) );
  426. $this->assertSame( array( $term_ids[0], $term_ids[1], 1 ), wp_list_pluck( $terms, 'term_id' ) );
  427. // Flip the order.
  428. wp_set_object_terms( $post_id, array( $term_ids[1], $term_ids[0] ), 'wptests_tax' );
  429. $terms = wp_get_object_terms( $post_id, array( 'category', 'wptests_tax' ) );
  430. $this->assertSame( array( $term_ids[1], $term_ids[0], 1 ), wp_list_pluck( $terms, 'term_id' ) );
  431. }
  432. /**
  433. * @ticket 41293
  434. */
  435. public function test_should_allow_same_args_with_the_get_terms() {
  436. register_post_type( 'wptests_pt' );
  437. register_taxonomy( 'wptests_tax', 'wptests_pt' );
  438. $t1 = self::factory()->term->create(
  439. array(
  440. 'taxonomy' => 'wptests_tax',
  441. 'name' => 'foo',
  442. 'slug' => 'bar',
  443. )
  444. );
  445. $t2 = self::factory()->term->create(
  446. array(
  447. 'taxonomy' => 'wptests_tax',
  448. 'name' => 'bar',
  449. 'slug' => 'foo',
  450. )
  451. );
  452. $p = self::factory()->post->create(
  453. array(
  454. 'post_type' => 'wptests_pt',
  455. )
  456. );
  457. wp_set_object_terms( $p, array( $t1, $t2 ), 'wptests_tax' );
  458. $expected = wp_get_post_terms(
  459. $p,
  460. 'wptests_tax',
  461. array(
  462. 'fields' => 'ids',
  463. )
  464. );
  465. $found1 = array_keys(
  466. wp_get_object_terms(
  467. $p,
  468. 'wptests_tax',
  469. array(
  470. 'fields' => 'id=>parent',
  471. )
  472. )
  473. );
  474. $found2 = array_keys(
  475. wp_get_object_terms(
  476. $p,
  477. 'wptests_tax',
  478. array(
  479. 'fields' => 'id=>slug',
  480. )
  481. )
  482. );
  483. $found3 = array_keys(
  484. wp_get_object_terms(
  485. $p,
  486. 'wptests_tax',
  487. array(
  488. 'fields' => 'id=>name',
  489. )
  490. )
  491. );
  492. $this->assertSame( $expected, $found1 );
  493. $this->assertSame( $expected, $found2 );
  494. $this->assertSame( $expected, $found3 );
  495. }
  496. /**
  497. * The query method should return zero for field as count and parent set.
  498. *
  499. * @ticket 42327
  500. */
  501. public function test_query_should_return_zero_for_field_count_and_parent_set() {
  502. $post_id = self::factory()->post->create();
  503. register_taxonomy( 'wptests_tax', 'post' );
  504. $term_id = self::factory()->term->create(
  505. array(
  506. 'taxonomy' => 'wptests_tax',
  507. )
  508. );
  509. wp_set_object_terms( $post_id, array( $term_id ), 'wptests_tax' );
  510. $q = new WP_Term_Query();
  511. $args = array(
  512. 'taxonomy' => 'wptests_tax',
  513. 'parent' => $term_id,
  514. 'fields' => 'count',
  515. );
  516. $this->assertSame( 0, $q->query( $args ) );
  517. }
  518. /**
  519. * The query method should return zero for field as count and child_of set.
  520. *
  521. * @ticket 42327
  522. */
  523. public function test_query_should_return_zero_for_field_as_count_and_child_of_set() {
  524. $post_id = self::factory()->post->create();
  525. register_taxonomy( 'wptests_tax', 'post' );
  526. $term_id = self::factory()->term->create(
  527. array(
  528. 'taxonomy' => 'wptests_tax',
  529. )
  530. );
  531. wp_set_object_terms( $post_id, array( $term_id ), 'wptests_tax' );
  532. $q = new WP_Term_Query();
  533. $args = array(
  534. 'taxonomy' => 'wptests_tax',
  535. 'child_of' => $term_id,
  536. 'fields' => 'count',
  537. );
  538. $this->assertSame( 0, $q->query( $args ) );
  539. }
  540. /**
  541. * The terms property should be an empty array for fields not as count and parent set.
  542. *
  543. * @ticket 42327
  544. */
  545. public function test_terms_property_should_be_empty_array_for_field_not_as_count_and_parent_set() {
  546. $post_id = self::factory()->post->create();
  547. register_taxonomy( 'wptests_tax', 'post' );
  548. $term_id = self::factory()->term->create(
  549. array(
  550. 'taxonomy' => 'wptests_tax',
  551. )
  552. );
  553. wp_set_object_terms( $post_id, array( $term_id ), 'wptests_tax' );
  554. $q = new WP_Term_Query(
  555. array(
  556. 'taxonomy' => 'wptests_tax',
  557. 'parent' => $term_id,
  558. )
  559. );
  560. $this->assertSame( array(), $q->terms );
  561. }
  562. /**
  563. * @ticket 42691
  564. */
  565. public function test_null_term_object_should_be_discarded() {
  566. register_taxonomy( 'wptests_tax', 'post' );
  567. $terms = self::factory()->term->create_many(
  568. 3,
  569. array(
  570. 'taxonomy' => 'wptests_tax',
  571. )
  572. );
  573. $this->term_id = $terms[1];
  574. add_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
  575. $found = get_terms(
  576. array(
  577. 'taxonomy' => 'wptests_tax',
  578. 'hide_empty' => false,
  579. )
  580. );
  581. remove_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
  582. $expected = array( $terms[0], $terms[2] );
  583. $this->assertSameSets( $expected, wp_list_pluck( $found, 'term_id' ) );
  584. }
  585. public function filter_term_to_null( $term ) {
  586. if ( $this->term_id === $term->term_id ) {
  587. return null;
  588. }
  589. return $term;
  590. }
  591. /**
  592. * @ticket 42691
  593. */
  594. public function test_error_term_object_should_be_discarded() {
  595. register_taxonomy( 'wptests_tax', 'post' );
  596. $terms = self::factory()->term->create_many(
  597. 3,
  598. array(
  599. 'taxonomy' => 'wptests_tax',
  600. )
  601. );
  602. $this->term_id = $terms[1];
  603. add_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
  604. $found = get_terms(
  605. array(
  606. 'taxonomy' => 'wptests_tax',
  607. 'hide_empty' => false,
  608. )
  609. );
  610. remove_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
  611. $expected = array( $terms[0], $terms[2] );
  612. $this->assertSameSets( $expected, wp_list_pluck( $found, 'term_id' ) );
  613. }
  614. public function filter_term_to_wp_error( $term ) {
  615. if ( $this->term_id === $term->term_id ) {
  616. return new WP_Error( 'foo' );
  617. }
  618. return $term;
  619. }
  620. /**
  621. * @ticket 41246
  622. */
  623. public function test_terms_pre_query_filter_should_bypass_database_query() {
  624. global $wpdb;
  625. add_filter( 'terms_pre_query', array( __CLASS__, 'filter_terms_pre_query' ), 10, 2 );
  626. $num_queries = $wpdb->num_queries;
  627. $q = new WP_Term_Query();
  628. $results = $q->query(
  629. array(
  630. 'fields' => 'ids',
  631. )
  632. );
  633. remove_filter( 'terms_pre_query', array( __CLASS__, 'filter_terms_pre_query' ), 10, 2 );
  634. // Make sure no queries were executed.
  635. $this->assertSame( $num_queries, $wpdb->num_queries );
  636. // We manually inserted a non-existing term and overrode the results with it.
  637. $this->assertSame( array( 555 ), $q->terms );
  638. }
  639. public static function filter_terms_pre_query( $terms, $query ) {
  640. return array( 555 );
  641. }
  642. /**
  643. * @ticket 37728
  644. */
  645. public function test_hide_empty_should_include_empty_parents_of_nonempty_children() {
  646. register_taxonomy(
  647. 'wptests_tax',
  648. 'post',
  649. array(
  650. 'hierarchical' => true,
  651. )
  652. );
  653. $t1 = self::factory()->term->create(
  654. array(
  655. 'taxonomy' => 'wptests_tax',
  656. )
  657. );
  658. $t2 = self::factory()->term->create(
  659. array(
  660. 'taxonomy' => 'wptests_tax',
  661. 'parent' => $t1,
  662. )
  663. );
  664. $p = self::factory()->post->create();
  665. wp_set_object_terms( $p, $t2, 'wptests_tax' );
  666. $q = new WP_Term_Query(
  667. array(
  668. 'taxonomy' => 'wptests_tax',
  669. 'hide_empty' => true,
  670. 'fields' => 'ids',
  671. )
  672. );
  673. $this->assertContains( $t1, $q->terms );
  674. }
  675. /**
  676. * @ticket 37728
  677. */
  678. public function test_hide_empty_should_include_empty_parents_of_nonempty_children_when_category_is_unspecified() {
  679. register_taxonomy(
  680. 'wptests_tax',
  681. 'post',
  682. array(
  683. 'hierarchical' => true,
  684. )
  685. );
  686. $t1 = self::factory()->term->create(
  687. array(
  688. 'taxonomy' => 'wptests_tax',
  689. )
  690. );
  691. $t2 = self::factory()->term->create(
  692. array(
  693. 'taxonomy' => 'wptests_tax',
  694. 'parent' => $t1,
  695. )
  696. );
  697. $p = self::factory()->post->create();
  698. wp_set_object_terms( $p, $t2, 'wptests_tax' );
  699. $q = new WP_Term_Query(
  700. array(
  701. 'hide_empty' => true,
  702. 'fields' => 'ids',
  703. )
  704. );
  705. $this->assertContains( $t1, $q->terms );
  706. }
  707. }