wpListCategories.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. <?php
  2. /**
  3. * @group taxonomy
  4. */
  5. class Tests_Category_WpListCategories extends WP_UnitTestCase {
  6. public function test_class() {
  7. $c = self::factory()->category->create();
  8. $found = wp_list_categories(
  9. array(
  10. 'hide_empty' => false,
  11. 'echo' => false,
  12. )
  13. );
  14. $this->assertContains( 'class="cat-item cat-item-' . $c . '"', $found );
  15. }
  16. public function test_class_containing_current_cat() {
  17. $c1 = self::factory()->category->create();
  18. $c2 = self::factory()->category->create();
  19. $found = wp_list_categories(
  20. array(
  21. 'hide_empty' => false,
  22. 'echo' => false,
  23. 'current_category' => $c2,
  24. )
  25. );
  26. $this->assertNotRegExp( '/class="[^"]*cat-item-' . $c1 . '[^"]*current-cat[^"]*"/', $found );
  27. $this->assertRegExp( '/class="[^"]*cat-item-' . $c2 . '[^"]*current-cat[^"]*"/', $found );
  28. }
  29. public function test_class_containing_current_cat_parent() {
  30. $c1 = self::factory()->category->create();
  31. $c2 = self::factory()->category->create(
  32. array(
  33. 'parent' => $c1,
  34. )
  35. );
  36. $found = wp_list_categories(
  37. array(
  38. 'hide_empty' => false,
  39. 'echo' => false,
  40. 'current_category' => $c2,
  41. )
  42. );
  43. $this->assertRegExp( '/class="[^"]*cat-item-' . $c1 . '[^"]*current-cat-parent[^"]*"/', $found );
  44. $this->assertNotRegExp( '/class="[^"]*cat-item-' . $c2 . '[^"]*current-cat-parent[^"]*"/', $found );
  45. }
  46. /**
  47. * @ticket 33565
  48. */
  49. public function test_current_category_should_accept_an_array_of_ids() {
  50. $cats = self::factory()->category->create_many( 3 );
  51. $found = wp_list_categories(
  52. array(
  53. 'echo' => false,
  54. 'hide_empty' => false,
  55. 'current_category' => array( $cats[0], $cats[2] ),
  56. )
  57. );
  58. $this->assertRegExp( '/class="[^"]*cat-item-' . $cats[0] . '[^"]*current-cat[^"]*"/', $found );
  59. $this->assertNotRegExp( '/class="[^"]*cat-item-' . $cats[1] . '[^"]*current[^"]*"/', $found );
  60. $this->assertRegExp( '/class="[^"]*cat-item-' . $cats[2] . '[^"]*current-cat[^"]*"/', $found );
  61. }
  62. /**
  63. * @ticket 16792
  64. */
  65. public function test_should_not_create_element_when_cat_name_is_filtered_to_empty_string() {
  66. $c1 = self::factory()->category->create(
  67. array(
  68. 'name' => 'Test Cat 1',
  69. )
  70. );
  71. $c2 = self::factory()->category->create(
  72. array(
  73. 'name' => 'Test Cat 2',
  74. )
  75. );
  76. add_filter( 'list_cats', array( $this, 'list_cats_callback' ) );
  77. $found = wp_list_categories(
  78. array(
  79. 'hide_empty' => false,
  80. 'echo' => false,
  81. )
  82. );
  83. remove_filter( 'list_cats', array( $this, 'list_cats_callback' ) );
  84. $this->assertContains( "cat-item-$c2", $found );
  85. $this->assertContains( 'Test Cat 2', $found );
  86. $this->assertNotContains( "cat-item-$c1", $found );
  87. $this->assertNotContains( 'Test Cat 1', $found );
  88. }
  89. public function list_cats_callback( $cat ) {
  90. if ( 'Test Cat 1' === $cat ) {
  91. return '';
  92. }
  93. return $cat;
  94. }
  95. /**
  96. * @ticket 44872
  97. */
  98. public function test_should_create_element_when_cat_name_is_zero() {
  99. $c = self::factory()->category->create(
  100. array(
  101. 'name' => '0',
  102. )
  103. );
  104. $found = wp_list_categories(
  105. array(
  106. 'hide_empty' => false,
  107. 'echo' => false,
  108. )
  109. );
  110. $this->assertContains( "cat-item-$c", $found );
  111. $this->assertContains( '0', $found );
  112. }
  113. public function test_show_option_all_link_should_go_to_home_page_when_show_on_front_is_false() {
  114. $cats = self::factory()->category->create_many( 2 );
  115. $found = wp_list_categories(
  116. array(
  117. 'echo' => false,
  118. 'show_option_all' => 'All',
  119. 'hide_empty' => false,
  120. 'taxonomy' => 'category',
  121. )
  122. );
  123. $this->assertContains( "<li class='cat-item-all'><a href='" . home_url( '/' ) . "'>All</a></li>", $found );
  124. }
  125. public function test_show_option_all_link_should_respect_page_for_posts() {
  126. $cats = self::factory()->category->create_many( 2 );
  127. $p = self::factory()->post->create( array( 'post_type' => 'page' ) );
  128. update_option( 'show_on_front', 'page' );
  129. update_option( 'page_for_posts', $p );
  130. $found = wp_list_categories(
  131. array(
  132. 'echo' => false,
  133. 'show_option_all' => 'All',
  134. 'hide_empty' => false,
  135. 'taxonomy' => 'category',
  136. )
  137. );
  138. $this->assertContains( "<li class='cat-item-all'><a href='" . get_permalink( $p ) . "'>All</a></li>", $found );
  139. }
  140. /**
  141. * @ticket 21881
  142. */
  143. public function test_show_option_all_link_should_link_to_post_type_archive_when_taxonomy_does_not_apply_to_posts() {
  144. register_post_type( 'wptests_pt', array( 'has_archive' => true ) );
  145. register_post_type( 'wptests_pt2', array( 'has_archive' => true ) );
  146. register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) );
  147. $terms = self::factory()->term->create_many(
  148. 2,
  149. array(
  150. 'taxonomy' => 'wptests_tax',
  151. )
  152. );
  153. $found = wp_list_categories(
  154. array(
  155. 'echo' => false,
  156. 'show_option_all' => 'All',
  157. 'hide_empty' => false,
  158. 'taxonomy' => 'wptests_tax',
  159. )
  160. );
  161. $pt_archive = get_post_type_archive_link( 'wptests_pt' );
  162. $this->assertContains( "<li class='cat-item-all'><a href='" . $pt_archive . "'>All</a></li>", $found );
  163. }
  164. /**
  165. * @ticket 21881
  166. */
  167. public function test_show_option_all_link_should_not_link_to_post_type_archive_if_has_archive_is_false() {
  168. register_post_type( 'wptests_pt', array( 'has_archive' => false ) );
  169. register_post_type( 'wptests_pt2', array( 'has_archive' => true ) );
  170. register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) );
  171. $terms = self::factory()->term->create_many(
  172. 2,
  173. array(
  174. 'taxonomy' => 'wptests_tax',
  175. )
  176. );
  177. $found = wp_list_categories(
  178. array(
  179. 'echo' => false,
  180. 'show_option_all' => 'All',
  181. 'hide_empty' => false,
  182. 'taxonomy' => 'wptests_tax',
  183. )
  184. );
  185. $pt_archive = get_post_type_archive_link( 'wptests_pt2' );
  186. $this->assertContains( "<li class='cat-item-all'><a href='" . $pt_archive . "'>All</a></li>", $found );
  187. }
  188. public function test_show_option_all_link_should_link_to_post_archive_if_available() {
  189. register_post_type( 'wptests_pt', array( 'has_archive' => true ) );
  190. register_post_type( 'wptests_pt2', array( 'has_archive' => true ) );
  191. register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'post', 'wptests_pt2' ) );
  192. $terms = self::factory()->term->create_many(
  193. 2,
  194. array(
  195. 'taxonomy' => 'wptests_tax',
  196. )
  197. );
  198. $found = wp_list_categories(
  199. array(
  200. 'echo' => false,
  201. 'show_option_all' => 'All',
  202. 'hide_empty' => false,
  203. 'taxonomy' => 'wptests_tax',
  204. )
  205. );
  206. $url = home_url( '/' );
  207. $this->assertContains( "<li class='cat-item-all'><a href='" . $url . "'>All</a></li>", $found );
  208. }
  209. public function test_show_option_all_link_should_link_to_post_archive_if_no_associated_post_types_have_archives() {
  210. register_post_type( 'wptests_pt', array( 'has_archive' => false ) );
  211. register_post_type( 'wptests_pt2', array( 'has_archive' => false ) );
  212. register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) );
  213. $terms = self::factory()->term->create_many(
  214. 2,
  215. array(
  216. 'taxonomy' => 'wptests_tax',
  217. )
  218. );
  219. $found = wp_list_categories(
  220. array(
  221. 'echo' => false,
  222. 'show_option_all' => 'All',
  223. 'hide_empty' => false,
  224. 'taxonomy' => 'wptests_tax',
  225. )
  226. );
  227. $url = home_url( '/' );
  228. $this->assertContains( "<li class='cat-item-all'><a href='" . $url . "'>All</a></li>", $found );
  229. }
  230. /**
  231. * @ticket 33460
  232. */
  233. public function test_title_li_should_be_shown_by_default_for_empty_lists() {
  234. $found = wp_list_categories(
  235. array(
  236. 'echo' => false,
  237. )
  238. );
  239. $this->assertContains( '<li class="categories">Categories', $found );
  240. }
  241. /**
  242. * @ticket 33460
  243. */
  244. public function test_hide_title_if_empty_should_be_respected_for_empty_lists_when_true() {
  245. $found = wp_list_categories(
  246. array(
  247. 'echo' => false,
  248. 'hide_title_if_empty' => true,
  249. )
  250. );
  251. $this->assertNotContains( '<li class="categories">Categories', $found );
  252. }
  253. /**
  254. * @ticket 33460
  255. */
  256. public function test_hide_title_if_empty_should_be_respected_for_empty_lists_when_false() {
  257. $found = wp_list_categories(
  258. array(
  259. 'echo' => false,
  260. 'hide_title_if_empty' => false,
  261. )
  262. );
  263. $this->assertContains( '<li class="categories">Categories', $found );
  264. }
  265. /**
  266. * @ticket 33460
  267. */
  268. public function test_hide_title_if_empty_should_be_ignored_when_category_list_is_not_empty() {
  269. $cat = self::factory()->category->create();
  270. $found = wp_list_categories(
  271. array(
  272. 'echo' => false,
  273. 'hide_empty' => false,
  274. 'hide_title_if_empty' => true,
  275. )
  276. );
  277. $this->assertContains( '<li class="categories">Categories', $found );
  278. }
  279. /**
  280. * @ticket 38839
  281. */
  282. public function test_hide_title_if_empty_should_not_output_stray_closing_tags() {
  283. $cat = self::factory()->category->create();
  284. $found = wp_list_categories(
  285. array(
  286. 'echo' => false,
  287. 'show_option_none' => '',
  288. 'child_of' => 1,
  289. 'hide_title_if_empty' => true,
  290. )
  291. );
  292. $this->assertNotContains( '</ul></li>', $found );
  293. }
  294. /**
  295. * @ticket 12981
  296. */
  297. public function test_exclude_tree_should_be_respected() {
  298. $c = self::factory()->category->create();
  299. $parent = self::factory()->category->create(
  300. array(
  301. 'name' => 'Parent',
  302. 'slug' => 'parent',
  303. )
  304. );
  305. $child = self::factory()->category->create(
  306. array(
  307. 'name' => 'Child',
  308. 'slug' => 'child',
  309. 'parent' => $parent,
  310. )
  311. );
  312. $args = array(
  313. 'echo' => 0,
  314. 'hide_empty' => 0,
  315. 'exclude_tree' => $parent,
  316. );
  317. $actual = wp_list_categories( $args );
  318. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent . '">', $actual );
  319. $this->assertNotContains( '<li class="cat-item cat-item-' . $child . '">', $actual );
  320. }
  321. /**
  322. * @ticket 12981
  323. */
  324. public function test_exclude_tree_should_be_merged_with_exclude() {
  325. $c = self::factory()->category->create();
  326. $parent = self::factory()->category->create(
  327. array(
  328. 'name' => 'Parent',
  329. 'slug' => 'parent',
  330. )
  331. );
  332. $child = self::factory()->category->create(
  333. array(
  334. 'name' => 'Child',
  335. 'slug' => 'child',
  336. 'parent' => $parent,
  337. )
  338. );
  339. $parent2 = self::factory()->category->create(
  340. array(
  341. 'name' => 'Parent',
  342. 'slug' => 'parent2',
  343. )
  344. );
  345. $child2 = self::factory()->category->create(
  346. array(
  347. 'name' => 'Child',
  348. 'slug' => 'child2',
  349. 'parent' => $parent2,
  350. )
  351. );
  352. $args = array(
  353. 'echo' => 0,
  354. 'hide_empty' => 0,
  355. 'exclude_tree' => $parent,
  356. );
  357. $actual = wp_list_categories(
  358. array(
  359. 'echo' => 0,
  360. 'hide_empty' => 0,
  361. 'exclude' => $parent,
  362. 'exclude_tree' => $parent2,
  363. )
  364. );
  365. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent . '">', $actual );
  366. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent2 . '">', $actual );
  367. $this->assertNotContains( '<li class="cat-item cat-item-' . $child . '">', $actual );
  368. $this->assertNotContains( '<li class="cat-item cat-item-' . $child2 . '">', $actual );
  369. }
  370. /**
  371. * @ticket 35156
  372. */
  373. public function test_comma_separated_exclude_tree_should_be_merged_with_exclude() {
  374. $c = self::factory()->category->create();
  375. $parent = self::factory()->category->create(
  376. array(
  377. 'name' => 'Parent',
  378. 'slug' => 'parent',
  379. )
  380. );
  381. $child = self::factory()->category->create(
  382. array(
  383. 'name' => 'Child',
  384. 'slug' => 'child',
  385. 'parent' => $parent,
  386. )
  387. );
  388. $parent2 = self::factory()->category->create(
  389. array(
  390. 'name' => 'Parent',
  391. 'slug' => 'parent2',
  392. )
  393. );
  394. $child2 = self::factory()->category->create(
  395. array(
  396. 'name' => 'Child',
  397. 'slug' => 'child2',
  398. 'parent' => $parent2,
  399. )
  400. );
  401. $parent3 = self::factory()->category->create(
  402. array(
  403. 'name' => 'Parent',
  404. 'slug' => 'parent3',
  405. )
  406. );
  407. $child3 = self::factory()->category->create(
  408. array(
  409. 'name' => 'Child',
  410. 'slug' => 'child3',
  411. 'parent' => $parent3,
  412. )
  413. );
  414. $parent4 = self::factory()->category->create(
  415. array(
  416. 'name' => 'Parent',
  417. 'slug' => 'parent4',
  418. )
  419. );
  420. $child4 = self::factory()->category->create(
  421. array(
  422. 'name' => 'Child',
  423. 'slug' => 'child4',
  424. 'parent' => $parent4,
  425. )
  426. );
  427. $args = array(
  428. 'echo' => 0,
  429. 'hide_empty' => 0,
  430. 'exclude_tree' => $parent,
  431. );
  432. $actual = wp_list_categories(
  433. array(
  434. 'echo' => 0,
  435. 'hide_empty' => 0,
  436. 'exclude' => "$parent,$parent2",
  437. 'exclude_tree' => "$parent3,$parent4",
  438. )
  439. );
  440. $this->assertContains( '<li class="cat-item cat-item-' . $c . '">', $actual );
  441. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent . '">', $actual );
  442. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent2 . '">', $actual );
  443. $this->assertNotContains( '<li class="cat-item cat-item-' . $child . '">', $actual );
  444. $this->assertNotContains( '<li class="cat-item cat-item-' . $child2 . '">', $actual );
  445. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent3 . '">', $actual );
  446. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent4 . '">', $actual );
  447. $this->assertNotContains( '<li class="cat-item cat-item-' . $child3 . '">', $actual );
  448. $this->assertNotContains( '<li class="cat-item cat-item-' . $child4 . '">', $actual );
  449. }
  450. /**
  451. * @ticket 35156
  452. */
  453. public function test_array_exclude_tree_should_be_merged_with_exclude() {
  454. $c = self::factory()->category->create();
  455. $parent = self::factory()->category->create(
  456. array(
  457. 'name' => 'Parent',
  458. 'slug' => 'parent',
  459. )
  460. );
  461. $child = self::factory()->category->create(
  462. array(
  463. 'name' => 'Child',
  464. 'slug' => 'child',
  465. 'parent' => $parent,
  466. )
  467. );
  468. $parent2 = self::factory()->category->create(
  469. array(
  470. 'name' => 'Parent',
  471. 'slug' => 'parent2',
  472. )
  473. );
  474. $child2 = self::factory()->category->create(
  475. array(
  476. 'name' => 'Child',
  477. 'slug' => 'child2',
  478. 'parent' => $parent2,
  479. )
  480. );
  481. $parent3 = self::factory()->category->create(
  482. array(
  483. 'name' => 'Parent',
  484. 'slug' => 'parent3',
  485. )
  486. );
  487. $child3 = self::factory()->category->create(
  488. array(
  489. 'name' => 'Child',
  490. 'slug' => 'child3',
  491. 'parent' => $parent3,
  492. )
  493. );
  494. $parent4 = self::factory()->category->create(
  495. array(
  496. 'name' => 'Parent',
  497. 'slug' => 'parent4',
  498. )
  499. );
  500. $child4 = self::factory()->category->create(
  501. array(
  502. 'name' => 'Child',
  503. 'slug' => 'child4',
  504. 'parent' => $parent4,
  505. )
  506. );
  507. $args = array(
  508. 'echo' => 0,
  509. 'hide_empty' => 0,
  510. 'exclude_tree' => $parent,
  511. );
  512. $actual = wp_list_categories(
  513. array(
  514. 'echo' => 0,
  515. 'hide_empty' => 0,
  516. 'exclude' => array( $parent, $parent2 ),
  517. 'exclude_tree' => array( $parent3, $parent4 ),
  518. )
  519. );
  520. $this->assertContains( '<li class="cat-item cat-item-' . $c . '">', $actual );
  521. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent . '">', $actual );
  522. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent2 . '">', $actual );
  523. $this->assertNotContains( '<li class="cat-item cat-item-' . $child . '">', $actual );
  524. $this->assertNotContains( '<li class="cat-item cat-item-' . $child2 . '">', $actual );
  525. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent3 . '">', $actual );
  526. $this->assertNotContains( '<li class="cat-item cat-item-' . $parent4 . '">', $actual );
  527. $this->assertNotContains( '<li class="cat-item cat-item-' . $child3 . '">', $actual );
  528. $this->assertNotContains( '<li class="cat-item cat-item-' . $child4 . '">', $actual );
  529. }
  530. /**
  531. * @ticket 10676
  532. */
  533. public function test_class_containing_current_cat_ancestor() {
  534. $parent = self::factory()->category->create(
  535. array(
  536. 'name' => 'Parent',
  537. 'slug' => 'parent',
  538. )
  539. );
  540. $child = self::factory()->category->create(
  541. array(
  542. 'name' => 'Child',
  543. 'slug' => 'child',
  544. 'parent' => $parent,
  545. )
  546. );
  547. $child2 = self::factory()->category->create(
  548. array(
  549. 'name' => 'Child 2',
  550. 'slug' => 'child2',
  551. 'parent' => $parent,
  552. )
  553. );
  554. $grandchild = self::factory()->category->create(
  555. array(
  556. 'name' => 'Grand Child',
  557. 'slug' => 'child',
  558. 'parent' => $child,
  559. )
  560. );
  561. $actual = wp_list_categories(
  562. array(
  563. 'echo' => 0,
  564. 'hide_empty' => false,
  565. 'current_category' => $grandchild,
  566. )
  567. );
  568. $this->assertRegExp( '/class="[^"]*cat-item-' . $parent . '[^"]*current-cat-ancestor[^"]*"/', $actual );
  569. $this->assertRegExp( '/class="[^"]*cat-item-' . $child . '[^"]*current-cat-ancestor[^"]*"/', $actual );
  570. $this->assertNotRegExp( '/class="[^"]*cat-item-' . $grandchild . '[^"]*current-cat-ancestor[^"]*"/', $actual );
  571. $this->assertNotRegExp( '/class="[^"]*cat-item-' . $child2 . '[^"]*current-cat-ancestor[^"]*"/', $actual );
  572. }
  573. }