/tests/phpunit/tests/post/getPages.php

https://gitlab.com/morganestes/wordpress-develop · PHP · 696 lines · 476 code · 104 blank · 116 comment · 0 complexity · c6f2eda0090dd5b1c35c7b3b4daa5b39 MD5 · raw file

  1. <?php
  2. /**
  3. * @group post
  4. */
  5. class Tests_Post_getPages extends WP_UnitTestCase {
  6. function setUp() {
  7. parent::setUp();
  8. }
  9. /**
  10. * @ticket 23167
  11. */
  12. function test_get_pages_cache() {
  13. global $wpdb;
  14. self::factory()->post->create_many( 3, array( 'post_type' => 'page' ) );
  15. wp_cache_delete( 'last_changed', 'posts' );
  16. $this->assertFalse( wp_cache_get( 'last_changed', 'posts' ) );
  17. $pages = get_pages();
  18. $this->assertEquals( 3, count( $pages ) );
  19. $this->assertNotEmpty( $time1 = wp_cache_get( 'last_changed', 'posts' ) );
  20. $num_queries = $wpdb->num_queries;
  21. foreach ( $pages as $page ) {
  22. $this->assertInstanceOf( 'WP_Post', $page );
  23. }
  24. // Again. num_queries and last_changed should remain the same.
  25. $pages = get_pages();
  26. $this->assertEquals( 3, count( $pages ) );
  27. $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'posts' ) );
  28. $this->assertEquals( $num_queries, $wpdb->num_queries );
  29. foreach ( $pages as $page ) {
  30. $this->assertInstanceOf( 'WP_Post', $page );
  31. }
  32. // Again with different args. last_changed should not increment because of
  33. // different args to get_pages(). num_queries should bump by 1.
  34. $pages = get_pages( array( 'number' => 2 ) );
  35. $this->assertEquals( 2, count( $pages ) );
  36. $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'posts' ) );
  37. $this->assertEquals( $num_queries + 1, $wpdb->num_queries );
  38. foreach ( $pages as $page ) {
  39. $this->assertInstanceOf( 'WP_Post', $page );
  40. }
  41. $num_queries = $wpdb->num_queries;
  42. // Again. num_queries and last_changed should remain the same.
  43. $pages = get_pages( array( 'number' => 2 ) );
  44. $this->assertEquals( 2, count( $pages ) );
  45. $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'posts' ) );
  46. $this->assertEquals( $num_queries, $wpdb->num_queries );
  47. foreach ( $pages as $page ) {
  48. $this->assertInstanceOf( 'WP_Post', $page );
  49. }
  50. // Do the first query again. The interim queries should not affect it.
  51. $pages = get_pages();
  52. $this->assertEquals( 3, count( $pages ) );
  53. $this->assertEquals( $time1, wp_cache_get( 'last_changed', 'posts' ) );
  54. $this->assertEquals( $num_queries, $wpdb->num_queries );
  55. foreach ( $pages as $page ) {
  56. $this->assertInstanceOf( 'WP_Post', $page );
  57. }
  58. // Force last_changed to increment.
  59. clean_post_cache( $pages[0]->ID );
  60. $this->assertNotEquals( $time1, $time2 = wp_cache_get( 'last_changed', 'posts' ) );
  61. $num_queries = $wpdb->num_queries;
  62. // last_changed bumped so num_queries should increment.
  63. $pages = get_pages( array( 'number' => 2 ) );
  64. $this->assertEquals( 2, count( $pages ) );
  65. $this->assertEquals( $time2, wp_cache_get( 'last_changed', 'posts' ) );
  66. $this->assertEquals( $num_queries + 1, $wpdb->num_queries );
  67. foreach ( $pages as $page ) {
  68. $this->assertInstanceOf( 'WP_Post', $page );
  69. }
  70. $last_changed = wp_cache_get( 'last_changed', 'posts' );
  71. // This should bump last_changed.
  72. wp_delete_post( $pages[0]->ID );
  73. $old_changed_float = $this->_microtime_to_float( $last_changed );
  74. $new_changed_float = $this->_microtime_to_float( wp_cache_get( 'last_changed', 'posts' ) );
  75. $this->assertGreaterThan( $old_changed_float, $new_changed_float );
  76. $num_queries = $wpdb->num_queries;
  77. $last_changed = wp_cache_get( 'last_changed', 'posts' );
  78. // num_queries should bump after wp_delete_post() bumps last_changed.
  79. $pages = get_pages();
  80. $this->assertEquals( 2, count( $pages ) );
  81. $this->assertEquals( $last_changed, wp_cache_get( 'last_changed', 'posts' ) );
  82. $this->assertEquals( $num_queries + 1, $wpdb->num_queries );
  83. foreach ( $pages as $page ) {
  84. $this->assertInstanceOf( 'WP_Post', $page );
  85. }
  86. }
  87. /**
  88. * @ticket 40669
  89. */
  90. public function test_cache_should_be_invalidated_by_add_post_meta() {
  91. $posts = self::factory()->post->create_many(
  92. 2, array(
  93. 'post_type' => 'page',
  94. )
  95. );
  96. add_post_meta( $posts[0], 'foo', 'bar' );
  97. $cached = get_pages(
  98. array(
  99. 'meta_key' => 'foo',
  100. 'meta_value' => 'bar',
  101. )
  102. );
  103. $cached_ids = wp_list_pluck( $cached, 'ID' );
  104. $this->assertEqualSets( array( $posts[0] ), $cached_ids );
  105. add_post_meta( $posts[1], 'foo', 'bar' );
  106. $found = get_pages(
  107. array(
  108. 'meta_key' => 'foo',
  109. 'meta_value' => 'bar',
  110. )
  111. );
  112. $found_ids = wp_list_pluck( $found, 'ID' );
  113. $this->assertEqualSets( $posts, $found_ids );
  114. }
  115. /**
  116. * @ticket 40669
  117. */
  118. public function test_cache_should_be_invalidated_by_update_post_meta() {
  119. $posts = self::factory()->post->create_many(
  120. 2, array(
  121. 'post_type' => 'page',
  122. )
  123. );
  124. add_post_meta( $posts[0], 'foo', 'bar' );
  125. add_post_meta( $posts[1], 'foo', 'bar' );
  126. $cached = get_pages(
  127. array(
  128. 'meta_key' => 'foo',
  129. 'meta_value' => 'bar',
  130. )
  131. );
  132. $cached_ids = wp_list_pluck( $cached, 'ID' );
  133. $this->assertEqualSets( $posts, $cached_ids );
  134. update_post_meta( $posts[1], 'foo', 'baz' );
  135. $found = get_pages(
  136. array(
  137. 'meta_key' => 'foo',
  138. 'meta_value' => 'bar',
  139. )
  140. );
  141. $found_ids = wp_list_pluck( $found, 'ID' );
  142. $this->assertEqualSets( array( $posts[0] ), $found_ids );
  143. }
  144. /**
  145. * @ticket 40669
  146. */
  147. public function test_cache_should_be_invalidated_by_delete_post_meta() {
  148. $posts = self::factory()->post->create_many(
  149. 2, array(
  150. 'post_type' => 'page',
  151. )
  152. );
  153. add_post_meta( $posts[0], 'foo', 'bar' );
  154. add_post_meta( $posts[1], 'foo', 'bar' );
  155. $cached = get_pages(
  156. array(
  157. 'meta_key' => 'foo',
  158. 'meta_value' => 'bar',
  159. )
  160. );
  161. $cached_ids = wp_list_pluck( $cached, 'ID' );
  162. $this->assertEqualSets( $posts, $cached_ids );
  163. delete_post_meta( $posts[1], 'foo' );
  164. $found = get_pages(
  165. array(
  166. 'meta_key' => 'foo',
  167. 'meta_value' => 'bar',
  168. )
  169. );
  170. $found_ids = wp_list_pluck( $found, 'ID' );
  171. $this->assertEqualSets( array( $posts[0] ), $found_ids );
  172. }
  173. /**
  174. * @ticket 40669
  175. */
  176. public function test_cache_should_be_invalidated_by_delete_post_meta_by_key() {
  177. $posts = self::factory()->post->create_many(
  178. 2, array(
  179. 'post_type' => 'page',
  180. )
  181. );
  182. add_post_meta( $posts[0], 'foo', 'bar' );
  183. add_post_meta( $posts[1], 'foo', 'bar' );
  184. $cached = get_pages(
  185. array(
  186. 'meta_key' => 'foo',
  187. 'meta_value' => 'bar',
  188. )
  189. );
  190. $cached_ids = wp_list_pluck( $cached, 'ID' );
  191. $this->assertEqualSets( $posts, $cached_ids );
  192. delete_post_meta_by_key( 'foo' );
  193. $found = get_pages(
  194. array(
  195. 'meta_key' => 'foo',
  196. 'meta_value' => 'bar',
  197. )
  198. );
  199. $found_ids = wp_list_pluck( $found, 'ID' );
  200. $this->assertEqualSets( array(), $found_ids );
  201. }
  202. /**
  203. * @ticket 20376
  204. */
  205. function test_get_pages_meta() {
  206. $posts = self::factory()->post->create_many( 3, array( 'post_type' => 'page' ) );
  207. add_post_meta( $posts[0], 'some-meta-key', '0' );
  208. add_post_meta( $posts[1], 'some-meta-key', '' );
  209. add_post_meta( $posts[2], 'some-meta-key', '1' );
  210. $this->assertEquals(
  211. 1, count(
  212. get_pages(
  213. array(
  214. 'meta_key' => 'some-meta-key',
  215. 'meta_value' => '0',
  216. )
  217. )
  218. )
  219. );
  220. $this->assertEquals(
  221. 1, count(
  222. get_pages(
  223. array(
  224. 'meta_key' => 'some-meta-key',
  225. 'meta_value' => '1',
  226. )
  227. )
  228. )
  229. );
  230. $this->assertEquals( 3, count( get_pages( array( 'meta_key' => 'some-meta-key' ) ) ) );
  231. }
  232. /**
  233. * @ticket 22074
  234. */
  235. function test_get_pages_include_exclude() {
  236. $page_ids = array();
  237. foreach ( range( 1, 20 ) as $i ) {
  238. $page_ids[] = self::factory()->post->create( array( 'post_type' => 'page' ) );
  239. }
  240. $inc = array_slice( $page_ids, 0, 10 );
  241. sort( $inc );
  242. $exc = array_slice( $page_ids, 10 );
  243. sort( $exc );
  244. $include = get_pages( array( 'include' => $inc ) );
  245. $inc_result = wp_list_pluck( $include, 'ID' );
  246. sort( $inc_result );
  247. $this->assertEquals( $inc, $inc_result );
  248. $exclude = get_pages( array( 'exclude' => $exc ) );
  249. $exc_result = wp_list_pluck( $exclude, 'ID' );
  250. sort( $exc_result );
  251. $this->assertEquals( $inc, $exc_result );
  252. }
  253. /**
  254. * @ticket 9470
  255. */
  256. function test_get_pages_parent() {
  257. $page_id1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  258. $page_id2 = self::factory()->post->create(
  259. array(
  260. 'post_type' => 'page',
  261. 'post_parent' => $page_id1,
  262. )
  263. );
  264. $page_id3 = self::factory()->post->create(
  265. array(
  266. 'post_type' => 'page',
  267. 'post_parent' => $page_id2,
  268. )
  269. );
  270. $page_id4 = self::factory()->post->create(
  271. array(
  272. 'post_type' => 'page',
  273. 'post_parent' => $page_id1,
  274. )
  275. );
  276. $pages = get_pages(
  277. array(
  278. 'parent' => 0,
  279. 'hierarchical' => false,
  280. )
  281. );
  282. $this->assertEqualSets( array( $page_id1 ), wp_list_pluck( $pages, 'ID' ) );
  283. $pages = get_pages(
  284. array(
  285. 'parent' => $page_id1,
  286. 'hierarchical' => false,
  287. )
  288. );
  289. $this->assertEqualSets( array( $page_id2, $page_id4 ), wp_list_pluck( $pages, 'ID' ) );
  290. $pages = get_pages(
  291. array(
  292. 'parent' => array( $page_id1, $page_id2 ),
  293. 'hierarchical' => false,
  294. )
  295. );
  296. $this->assertEqualSets( array( $page_id2, $page_id3, $page_id4 ), wp_list_pluck( $pages, 'ID' ) );
  297. $pages = get_pages( array( 'parent' => 0 ) );
  298. $this->assertEqualSets( array( $page_id1 ), wp_list_pluck( $pages, 'ID' ) );
  299. $pages = get_pages( array( 'parent' => $page_id1 ) );
  300. $this->assertEqualSets( array( $page_id2, $page_id4 ), wp_list_pluck( $pages, 'ID' ) );
  301. $pages = get_pages( array( 'parent' => array( $page_id1, $page_id2 ) ) );
  302. $this->assertEqualSets( array( $page_id2, $page_id3, $page_id4 ), wp_list_pluck( $pages, 'ID' ) );
  303. }
  304. /**
  305. * @ticket 22389
  306. */
  307. function test_wp_dropdown_pages() {
  308. self::factory()->post->create_many( 5, array( 'post_type' => 'page' ) );
  309. preg_match_all( '#<option#', wp_dropdown_pages( 'echo=0' ), $matches );
  310. $this->assertEquals( 5, count( $matches[0] ) );
  311. }
  312. /**
  313. * @ticket 22208
  314. */
  315. function test_get_chidren_fields_ids() {
  316. $post_id = self::factory()->post->create();
  317. $child_ids = self::factory()->post->create_many( 5, array( 'post_parent' => $post_id ) );
  318. $post_ids = get_children(
  319. array(
  320. 'fields' => 'ids',
  321. 'post_parent' => $post_id,
  322. )
  323. );
  324. $this->assertEqualSets( $child_ids, $post_ids );
  325. }
  326. /**
  327. * @ticket 25750
  328. */
  329. function test_get_pages_hierarchical_and_no_parent() {
  330. global $wpdb;
  331. $page_1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  332. $page_2 = self::factory()->post->create(
  333. array(
  334. 'post_type' => 'page',
  335. 'post_parent' => $page_1,
  336. )
  337. );
  338. $page_3 = self::factory()->post->create(
  339. array(
  340. 'post_type' => 'page',
  341. 'post_parent' => $page_1,
  342. )
  343. );
  344. $page_4 = self::factory()->post->create(
  345. array(
  346. 'post_type' => 'page',
  347. 'post_parent' => $page_2,
  348. )
  349. );
  350. $pages = get_pages(); // Defaults: hierarchical = true, parent = -1
  351. $pages_default_args = get_pages(
  352. array(
  353. 'hierarchical' => true,
  354. 'parent' => -1,
  355. )
  356. );
  357. // Confirm the defaults.
  358. $this->assertEquals( $pages, $pages_default_args );
  359. /*
  360. * Here's the tree we are testing:
  361. *
  362. * page 1
  363. * - page 2
  364. * -- page 4
  365. * - page 3
  366. *
  367. * If hierarchical => true works, the order will be 1,2,4,3.
  368. * If it doesn't, they will be in the creation order, 1,2,3,4.
  369. */
  370. $this->assertEqualSets( array( $page_1, $page_2, $page_4, $page_3 ), wp_list_pluck( $pages, 'ID' ) );
  371. }
  372. /**
  373. * @ticket 18701
  374. */
  375. public function test_get_pages_hierarchical_empty_child_of() {
  376. $page_1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  377. $page_2 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  378. $page_3 = self::factory()->post->create(
  379. array(
  380. 'post_type' => 'page',
  381. 'post_parent' => $page_1,
  382. )
  383. );
  384. $page_4 = self::factory()->post->create(
  385. array(
  386. 'post_type' => 'page',
  387. 'post_parent' => $page_1,
  388. )
  389. );
  390. $pages = get_pages(); // Defaults: hierarchical = true, child_of = '', parent = -1
  391. $default_args = get_pages(
  392. array(
  393. 'hierarchical' => true,
  394. 'child_of' => '',
  395. )
  396. );
  397. $this->assertEquals( $pages, $default_args );
  398. /*
  399. * Page tree:
  400. *
  401. * page 1 (parent 0)
  402. * – page 3 (parent 1)
  403. * – page 4 (parent 1)
  404. * page 2 (parent 0)
  405. *
  406. * With default arguments, if child_of is empty (normalized to 0), only pages with a matching
  407. * post_parent will be returned, in the order they were created: 1, 2.
  408. */
  409. $found_pages = wp_list_filter( $pages, array( 'post_parent' => 0 ) );
  410. $this->assertEqualSets( array( $page_1, $page_2 ), wp_list_pluck( $found_pages, 'ID' ) );
  411. }
  412. /**
  413. * @ticket 18701
  414. */
  415. public function test_get_pages_non_hierarchical_empty_child_of() {
  416. $page_1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  417. $page_2 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  418. $page_3 = self::factory()->post->create(
  419. array(
  420. 'post_type' => 'page',
  421. 'post_parent' => $page_1,
  422. )
  423. );
  424. $page_4 = self::factory()->post->create(
  425. array(
  426. 'post_type' => 'page',
  427. 'post_parent' => $page_1,
  428. )
  429. );
  430. $pages = get_pages( array( 'hierarchical' => false ) ); // child_of = '', parent = -1
  431. /*
  432. * Page tree:
  433. *
  434. * page 1 (parent 0)
  435. * – page 3 (parent 1)
  436. * – page 4 (parent 1)
  437. * page 2 (parent 0)
  438. *
  439. * If hierarchical is false and child_of is empty (normalized to 0), pages will be returned
  440. * in order of creation: 1, 2, 3, 4, regardless of parent.
  441. */
  442. $this->assertEqualSets( array( $page_1, $page_2, $page_3, $page_4 ), wp_list_pluck( $pages, 'ID' ) );
  443. }
  444. /**
  445. * @ticket 18701
  446. */
  447. public function test_get_pages_hierarchical_non_empty_child_of() {
  448. $page_1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  449. $page_2 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  450. $page_3 = self::factory()->post->create(
  451. array(
  452. 'post_type' => 'page',
  453. 'post_parent' => $page_1,
  454. )
  455. );
  456. $page_4 = self::factory()->post->create(
  457. array(
  458. 'post_type' => 'page',
  459. 'post_parent' => $page_3,
  460. )
  461. );
  462. $page_5 = self::factory()->post->create(
  463. array(
  464. 'post_type' => 'page',
  465. 'post_parent' => $page_1,
  466. )
  467. );
  468. $pages = get_pages( array( 'child_of' => $page_1 ) ); // Defaults: hierarchical = true, parent = -1.
  469. /*
  470. * Page tree:
  471. *
  472. * page 1 (parent 0)
  473. * – page 3 (parent 1)
  474. * –– page 4 (parent 3)
  475. * – page 5 (parent 1)
  476. * page 2 (parent 0)
  477. *
  478. * If hierarchical is true (default), and child_of is not empty, pages will be returned
  479. * hierarchically in order of creation: 3, 4, 5.
  480. */
  481. $this->assertEqualSets( array( $page_3, $page_4, $page_5 ), wp_list_pluck( $pages, 'ID' ) );
  482. }
  483. /**
  484. * @ticket 18701
  485. */
  486. public function test_get_pages_non_hierarchical_non_empty_child_of() {
  487. $page_1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  488. $page_2 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  489. $page_3 = self::factory()->post->create(
  490. array(
  491. 'post_type' => 'page',
  492. 'post_parent' => $page_1,
  493. )
  494. );
  495. $page_4 = self::factory()->post->create(
  496. array(
  497. 'post_type' => 'page',
  498. 'post_parent' => $page_3,
  499. )
  500. );
  501. $page_5 = self::factory()->post->create(
  502. array(
  503. 'post_type' => 'page',
  504. 'post_parent' => $page_1,
  505. )
  506. );
  507. $pages = get_pages(
  508. array(
  509. 'hierarchical' => false,
  510. 'child_of' => $page_1,
  511. )
  512. );
  513. /*
  514. * Page tree:
  515. *
  516. * page 1 (parent 0)
  517. * – page 3 (parent 1)
  518. * –– page 4 (parent 3)
  519. * – page 5 (parent 1)
  520. * page 2 (parent 0)
  521. *
  522. * If hierarchical is false, and child_of is not empty, pages will (apparently) be returned
  523. * hierarchically anyway in order of creation: 3, 4, 5.
  524. */
  525. $this->assertEqualSets( array( $page_3, $page_4, $page_5 ), wp_list_pluck( $pages, 'ID' ) );
  526. // How it should work.
  527. $found_pages = wp_list_filter( $pages, array( 'post_parent' => $page_1 ) );
  528. $this->assertEqualSets( array( $page_3, $page_5 ), wp_list_pluck( $found_pages, 'ID' ) );
  529. }
  530. function test_wp_list_pages_classes() {
  531. $type = 'taco';
  532. register_post_type(
  533. $type, array(
  534. 'hierarchical' => true,
  535. 'public' => true,
  536. )
  537. );
  538. $posts = self::factory()->post->create_many( 2, array( 'post_type' => $type ) );
  539. $post_id = reset( $posts );
  540. $this->go_to( "/?p=$post_id&post_type=$type" );
  541. $this->assertEquals( $post_id, get_queried_object_id() );
  542. $output = wp_list_pages(
  543. array(
  544. 'echo' => false,
  545. 'title_li' => '',
  546. 'post_type' => $type,
  547. )
  548. );
  549. $this->assertNotEmpty( $output );
  550. $this->assertEquals( 2, substr_count( $output, 'class="page_item ' ) );
  551. $this->assertContains( 'current_page_item', $output );
  552. $this->assertEquals( 1, substr_count( $output, 'current_page_item' ) );
  553. _unregister_post_type( $type );
  554. }
  555. function test_exclude_tree() {
  556. $post_id1 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  557. $post_id2 = self::factory()->post->create(
  558. array(
  559. 'post_type' => 'page',
  560. 'post_parent' => $post_id1,
  561. )
  562. );
  563. $post_id3 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  564. $post_id4 = self::factory()->post->create(
  565. array(
  566. 'post_type' => 'page',
  567. 'post_parent' => $post_id3,
  568. )
  569. );
  570. $all = get_pages();
  571. $this->assertCount( 4, $all );
  572. $exclude1 = get_pages( "exclude_tree=$post_id1" );
  573. $this->assertCount( 2, $exclude1 );
  574. $exclude2 = get_pages( array( 'exclude_tree' => $post_id1 ) );
  575. $this->assertCount( 2, $exclude2 );
  576. $exclude3 = get_pages( array( 'exclude_tree' => array( $post_id1 ) ) );
  577. $this->assertCount( 2, $exclude3 );
  578. $exclude4 = get_pages( array( 'exclude_tree' => array( $post_id1, $post_id2 ) ) );
  579. $this->assertCount( 2, $exclude4 );
  580. $exclude5 = get_pages( array( 'exclude_tree' => array( $post_id1, $post_id3 ) ) );
  581. $this->assertCount( 0, $exclude5 );
  582. $post_id5 = self::factory()->post->create( array( 'post_type' => 'page' ) );
  583. $post_id6 = self::factory()->post->create(
  584. array(
  585. 'post_type' => 'page',
  586. 'post_parent' => $post_id5,
  587. )
  588. );
  589. $exclude6 = get_pages( array( 'exclude_tree' => array( $post_id1, $post_id3 ) ) );
  590. $this->assertCount( 2, $exclude6 );
  591. }
  592. }