PageRenderTime 68ms CodeModel.GetById 42ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-includes/query.php

http://github.com/markjaquith/WordPress
PHP | 1196 lines | 385 code | 131 blank | 680 comment | 53 complexity | cf47a59d5a5d3d678cf1cb6e2881ecf5 MD5 | raw file
Possible License(s): 0BSD
  1. <?php
  2. /**
  3. * WordPress Query API
  4. *
  5. * The query API attempts to get which part of WordPress the user is on. It
  6. * also provides functionality for getting URL query information.
  7. *
  8. * @link https://developer.wordpress.org/themes/basics/the-loop/ More information on The Loop.
  9. *
  10. * @package WordPress
  11. * @subpackage Query
  12. */
  13. /**
  14. * Retrieve variable in the WP_Query class.
  15. *
  16. * @since 1.5.0
  17. * @since 3.9.0 The `$default` argument was introduced.
  18. *
  19. * @global WP_Query $wp_query WordPress Query object.
  20. *
  21. * @param string $var The variable key to retrieve.
  22. * @param mixed $default Optional. Value to return if the query variable is not set. Default empty.
  23. * @return mixed Contents of the query variable.
  24. */
  25. function get_query_var( $var, $default = '' ) {
  26. global $wp_query;
  27. return $wp_query->get( $var, $default );
  28. }
  29. /**
  30. * Retrieve the currently-queried object.
  31. *
  32. * Wrapper for WP_Query::get_queried_object().
  33. *
  34. * @since 3.1.0
  35. *
  36. * @global WP_Query $wp_query WordPress Query object.
  37. *
  38. * @return object Queried object.
  39. */
  40. function get_queried_object() {
  41. global $wp_query;
  42. return $wp_query->get_queried_object();
  43. }
  44. /**
  45. * Retrieve ID of the current queried object.
  46. *
  47. * Wrapper for WP_Query::get_queried_object_id().
  48. *
  49. * @since 3.1.0
  50. *
  51. * @global WP_Query $wp_query WordPress Query object.
  52. *
  53. * @return int ID of the queried object.
  54. */
  55. function get_queried_object_id() {
  56. global $wp_query;
  57. return $wp_query->get_queried_object_id();
  58. }
  59. /**
  60. * Set query variable.
  61. *
  62. * @since 2.2.0
  63. *
  64. * @global WP_Query $wp_query WordPress Query object.
  65. *
  66. * @param string $var Query variable key.
  67. * @param mixed $value Query variable value.
  68. */
  69. function set_query_var( $var, $value ) {
  70. global $wp_query;
  71. $wp_query->set( $var, $value );
  72. }
  73. /**
  74. * Sets up The Loop with query parameters.
  75. *
  76. * Note: This function will completely override the main query and isn't intended for use
  77. * by plugins or themes. Its overly-simplistic approach to modifying the main query can be
  78. * problematic and should be avoided wherever possible. In most cases, there are better,
  79. * more performant options for modifying the main query such as via the {@see 'pre_get_posts'}
  80. * action within WP_Query.
  81. *
  82. * This must not be used within the WordPress Loop.
  83. *
  84. * @since 1.5.0
  85. *
  86. * @global WP_Query $wp_query WordPress Query object.
  87. *
  88. * @param array|string $query Array or string of WP_Query arguments.
  89. * @return WP_Post[]|int[] Array of post objects or post IDs.
  90. */
  91. function query_posts( $query ) {
  92. $GLOBALS['wp_query'] = new WP_Query();
  93. return $GLOBALS['wp_query']->query( $query );
  94. }
  95. /**
  96. * Destroys the previous query and sets up a new query.
  97. *
  98. * This should be used after query_posts() and before another query_posts().
  99. * This will remove obscure bugs that occur when the previous WP_Query object
  100. * is not destroyed properly before another is set up.
  101. *
  102. * @since 2.3.0
  103. *
  104. * @global WP_Query $wp_query WordPress Query object.
  105. * @global WP_Query $wp_the_query Copy of the global WP_Query instance created during wp_reset_query().
  106. */
  107. function wp_reset_query() {
  108. $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
  109. wp_reset_postdata();
  110. }
  111. /**
  112. * After looping through a separate query, this function restores
  113. * the $post global to the current post in the main query.
  114. *
  115. * @since 3.0.0
  116. *
  117. * @global WP_Query $wp_query WordPress Query object.
  118. */
  119. function wp_reset_postdata() {
  120. global $wp_query;
  121. if ( isset( $wp_query ) ) {
  122. $wp_query->reset_postdata();
  123. }
  124. }
  125. /*
  126. * Query type checks.
  127. */
  128. /**
  129. * Determines whether the query is for an existing archive page.
  130. *
  131. * Month, Year, Category, Author, Post Type archive...
  132. *
  133. * For more information on this and similar theme functions, check out
  134. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  135. * Conditional Tags} article in the Theme Developer Handbook.
  136. *
  137. * @since 1.5.0
  138. *
  139. * @global WP_Query $wp_query WordPress Query object.
  140. *
  141. * @return bool
  142. */
  143. function is_archive() {
  144. global $wp_query;
  145. if ( ! isset( $wp_query ) ) {
  146. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  147. return false;
  148. }
  149. return $wp_query->is_archive();
  150. }
  151. /**
  152. * Determines whether the query is for an existing post type archive page.
  153. *
  154. * For more information on this and similar theme functions, check out
  155. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  156. * Conditional Tags} article in the Theme Developer Handbook.
  157. *
  158. * @since 3.1.0
  159. *
  160. * @global WP_Query $wp_query WordPress Query object.
  161. *
  162. * @param string|string[] $post_types Optional. Post type or array of posts types
  163. * to check against. Default empty.
  164. * @return bool
  165. */
  166. function is_post_type_archive( $post_types = '' ) {
  167. global $wp_query;
  168. if ( ! isset( $wp_query ) ) {
  169. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  170. return false;
  171. }
  172. return $wp_query->is_post_type_archive( $post_types );
  173. }
  174. /**
  175. * Determines whether the query is for an existing attachment page.
  176. *
  177. * For more information on this and similar theme functions, check out
  178. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  179. * Conditional Tags} article in the Theme Developer Handbook.
  180. *
  181. * @since 2.0.0
  182. *
  183. * @global WP_Query $wp_query WordPress Query object.
  184. *
  185. * @param int|string|int[]|string[] $attachment Optional. Attachment ID, title, slug, or array of such
  186. * to check against. Default empty.
  187. * @return bool
  188. */
  189. function is_attachment( $attachment = '' ) {
  190. global $wp_query;
  191. if ( ! isset( $wp_query ) ) {
  192. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  193. return false;
  194. }
  195. return $wp_query->is_attachment( $attachment );
  196. }
  197. /**
  198. * Determines whether the query is for an existing author archive page.
  199. *
  200. * If the $author parameter is specified, this function will additionally
  201. * check if the query is for one of the authors specified.
  202. *
  203. * For more information on this and similar theme functions, check out
  204. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  205. * Conditional Tags} article in the Theme Developer Handbook.
  206. *
  207. * @since 1.5.0
  208. *
  209. * @global WP_Query $wp_query WordPress Query object.
  210. *
  211. * @param int|string|int[]|string[] $author Optional. User ID, nickname, nicename, or array of such
  212. * to check against. Default empty.
  213. * @return bool
  214. */
  215. function is_author( $author = '' ) {
  216. global $wp_query;
  217. if ( ! isset( $wp_query ) ) {
  218. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  219. return false;
  220. }
  221. return $wp_query->is_author( $author );
  222. }
  223. /**
  224. * Determines whether the query is for an existing category archive page.
  225. *
  226. * If the $category parameter is specified, this function will additionally
  227. * check if the query is for one of the categories specified.
  228. *
  229. * For more information on this and similar theme functions, check out
  230. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  231. * Conditional Tags} article in the Theme Developer Handbook.
  232. *
  233. * @since 1.5.0
  234. *
  235. * @global WP_Query $wp_query WordPress Query object.
  236. *
  237. * @param int|string|int[]|string[] $category Optional. Category ID, name, slug, or array of such
  238. * to check against. Default empty.
  239. * @return bool
  240. */
  241. function is_category( $category = '' ) {
  242. global $wp_query;
  243. if ( ! isset( $wp_query ) ) {
  244. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  245. return false;
  246. }
  247. return $wp_query->is_category( $category );
  248. }
  249. /**
  250. * Determines whether the query is for an existing tag archive page.
  251. *
  252. * If the $tag parameter is specified, this function will additionally
  253. * check if the query is for one of the tags specified.
  254. *
  255. * For more information on this and similar theme functions, check out
  256. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  257. * Conditional Tags} article in the Theme Developer Handbook.
  258. *
  259. * @since 2.3.0
  260. *
  261. * @global WP_Query $wp_query WordPress Query object.
  262. *
  263. * @param int|string|int[]|string[] $tag Optional. Tag ID, name, slug, or array of such
  264. * to check against. Default empty.
  265. * @return bool
  266. */
  267. function is_tag( $tag = '' ) {
  268. global $wp_query;
  269. if ( ! isset( $wp_query ) ) {
  270. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  271. return false;
  272. }
  273. return $wp_query->is_tag( $tag );
  274. }
  275. /**
  276. * Determines whether the query is for an existing custom taxonomy archive page.
  277. *
  278. * If the $taxonomy parameter is specified, this function will additionally
  279. * check if the query is for that specific $taxonomy.
  280. *
  281. * If the $term parameter is specified in addition to the $taxonomy parameter,
  282. * this function will additionally check if the query is for one of the terms
  283. * specified.
  284. *
  285. * For more information on this and similar theme functions, check out
  286. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  287. * Conditional Tags} article in the Theme Developer Handbook.
  288. *
  289. * @since 2.5.0
  290. *
  291. * @global WP_Query $wp_query WordPress Query object.
  292. *
  293. * @param string|string[] $taxonomy Optional. Taxonomy slug or slugs to check against.
  294. * Default empty.
  295. * @param int|string|int[]|string[] $term Optional. Term ID, name, slug, or array of such
  296. * to check against. Default empty.
  297. * @return bool True for custom taxonomy archive pages, false for built-in taxonomies
  298. * (category and tag archives).
  299. */
  300. function is_tax( $taxonomy = '', $term = '' ) {
  301. global $wp_query;
  302. if ( ! isset( $wp_query ) ) {
  303. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  304. return false;
  305. }
  306. return $wp_query->is_tax( $taxonomy, $term );
  307. }
  308. /**
  309. * Determines whether the query is for an existing date archive.
  310. *
  311. * For more information on this and similar theme functions, check out
  312. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  313. * Conditional Tags} article in the Theme Developer Handbook.
  314. *
  315. * @since 1.5.0
  316. *
  317. * @global WP_Query $wp_query WordPress Query object.
  318. *
  319. * @return bool
  320. */
  321. function is_date() {
  322. global $wp_query;
  323. if ( ! isset( $wp_query ) ) {
  324. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  325. return false;
  326. }
  327. return $wp_query->is_date();
  328. }
  329. /**
  330. * Determines whether the query is for an existing day archive.
  331. *
  332. * A conditional check to test whether the page is a date-based archive page displaying posts for the current day.
  333. *
  334. * For more information on this and similar theme functions, check out
  335. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  336. * Conditional Tags} article in the Theme Developer Handbook.
  337. *
  338. * @since 1.5.0
  339. *
  340. * @global WP_Query $wp_query WordPress Query object.
  341. *
  342. * @return bool
  343. */
  344. function is_day() {
  345. global $wp_query;
  346. if ( ! isset( $wp_query ) ) {
  347. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  348. return false;
  349. }
  350. return $wp_query->is_day();
  351. }
  352. /**
  353. * Determines whether the query is for a feed.
  354. *
  355. * For more information on this and similar theme functions, check out
  356. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  357. * Conditional Tags} article in the Theme Developer Handbook.
  358. *
  359. * @since 1.5.0
  360. *
  361. * @global WP_Query $wp_query WordPress Query object.
  362. *
  363. * @param string|string[] $feeds Optional. Feed type or array of feed types
  364. * to check against. Default empty.
  365. * @return bool
  366. */
  367. function is_feed( $feeds = '' ) {
  368. global $wp_query;
  369. if ( ! isset( $wp_query ) ) {
  370. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  371. return false;
  372. }
  373. return $wp_query->is_feed( $feeds );
  374. }
  375. /**
  376. * Is the query for a comments feed?
  377. *
  378. * @since 3.0.0
  379. *
  380. * @global WP_Query $wp_query WordPress Query object.
  381. *
  382. * @return bool
  383. */
  384. function is_comment_feed() {
  385. global $wp_query;
  386. if ( ! isset( $wp_query ) ) {
  387. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  388. return false;
  389. }
  390. return $wp_query->is_comment_feed();
  391. }
  392. /**
  393. * Determines whether the query is for the front page of the site.
  394. *
  395. * This is for what is displayed at your site's main URL.
  396. *
  397. * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
  398. *
  399. * If you set a static page for the front page of your site, this function will return
  400. * true when viewing that page.
  401. *
  402. * Otherwise the same as @see is_home()
  403. *
  404. * For more information on this and similar theme functions, check out
  405. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  406. * Conditional Tags} article in the Theme Developer Handbook.
  407. *
  408. * @since 2.5.0
  409. *
  410. * @global WP_Query $wp_query WordPress Query object.
  411. *
  412. * @return bool True, if front of site.
  413. */
  414. function is_front_page() {
  415. global $wp_query;
  416. if ( ! isset( $wp_query ) ) {
  417. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  418. return false;
  419. }
  420. return $wp_query->is_front_page();
  421. }
  422. /**
  423. * Determines whether the query is for the blog homepage.
  424. *
  425. * The blog homepage is the page that shows the time-based blog content of the site.
  426. *
  427. * is_home() is dependent on the site's "Front page displays" Reading Settings 'show_on_front'
  428. * and 'page_for_posts'.
  429. *
  430. * If a static page is set for the front page of the site, this function will return true only
  431. * on the page you set as the "Posts page".
  432. *
  433. * For more information on this and similar theme functions, check out
  434. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  435. * Conditional Tags} article in the Theme Developer Handbook.
  436. *
  437. * @since 1.5.0
  438. *
  439. * @see is_front_page()
  440. * @global WP_Query $wp_query WordPress Query object.
  441. *
  442. * @return bool True if blog view homepage, otherwise false.
  443. */
  444. function is_home() {
  445. global $wp_query;
  446. if ( ! isset( $wp_query ) ) {
  447. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  448. return false;
  449. }
  450. return $wp_query->is_home();
  451. }
  452. /**
  453. * Determines whether the query is for the Privacy Policy page.
  454. *
  455. * The Privacy Policy page is the page that shows the Privacy Policy content of the site.
  456. *
  457. * is_privacy_policy() is dependent on the site's "Change your Privacy Policy page" Privacy Settings 'wp_page_for_privacy_policy'.
  458. *
  459. * This function will return true only on the page you set as the "Privacy Policy page".
  460. *
  461. * For more information on this and similar theme functions, check out
  462. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  463. * Conditional Tags} article in the Theme Developer Handbook.
  464. *
  465. * @since 5.2.0
  466. *
  467. * @global WP_Query $wp_query WordPress Query object.
  468. *
  469. * @return bool
  470. */
  471. function is_privacy_policy() {
  472. global $wp_query;
  473. if ( ! isset( $wp_query ) ) {
  474. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  475. return false;
  476. }
  477. return $wp_query->is_privacy_policy();
  478. }
  479. /**
  480. * Determines whether the query is for an existing month archive.
  481. *
  482. * For more information on this and similar theme functions, check out
  483. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  484. * Conditional Tags} article in the Theme Developer Handbook.
  485. *
  486. * @since 1.5.0
  487. *
  488. * @global WP_Query $wp_query WordPress Query object.
  489. *
  490. * @return bool
  491. */
  492. function is_month() {
  493. global $wp_query;
  494. if ( ! isset( $wp_query ) ) {
  495. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  496. return false;
  497. }
  498. return $wp_query->is_month();
  499. }
  500. /**
  501. * Determines whether the query is for an existing single page.
  502. *
  503. * If the $page parameter is specified, this function will additionally
  504. * check if the query is for one of the pages specified.
  505. *
  506. * For more information on this and similar theme functions, check out
  507. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  508. * Conditional Tags} article in the Theme Developer Handbook.
  509. *
  510. * @see is_single()
  511. * @see is_singular()
  512. *
  513. * @since 1.5.0
  514. *
  515. * @global WP_Query $wp_query WordPress Query object.
  516. *
  517. * @param int|string|int[]|string[] $page Optional. Page ID, title, slug, or array of such
  518. * to check against. Default empty.
  519. * @return bool Whether the query is for an existing single page.
  520. */
  521. function is_page( $page = '' ) {
  522. global $wp_query;
  523. if ( ! isset( $wp_query ) ) {
  524. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  525. return false;
  526. }
  527. return $wp_query->is_page( $page );
  528. }
  529. /**
  530. * Determines whether the query is for paged results and not for the first page.
  531. *
  532. * For more information on this and similar theme functions, check out
  533. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  534. * Conditional Tags} article in the Theme Developer Handbook.
  535. *
  536. * @since 1.5.0
  537. *
  538. * @global WP_Query $wp_query WordPress Query object.
  539. *
  540. * @return bool
  541. */
  542. function is_paged() {
  543. global $wp_query;
  544. if ( ! isset( $wp_query ) ) {
  545. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  546. return false;
  547. }
  548. return $wp_query->is_paged();
  549. }
  550. /**
  551. * Determines whether the query is for a post or page preview.
  552. *
  553. * For more information on this and similar theme functions, check out
  554. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  555. * Conditional Tags} article in the Theme Developer Handbook.
  556. *
  557. * @since 2.0.0
  558. *
  559. * @global WP_Query $wp_query WordPress Query object.
  560. *
  561. * @return bool
  562. */
  563. function is_preview() {
  564. global $wp_query;
  565. if ( ! isset( $wp_query ) ) {
  566. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  567. return false;
  568. }
  569. return $wp_query->is_preview();
  570. }
  571. /**
  572. * Is the query for the robots.txt file?
  573. *
  574. * @since 2.1.0
  575. *
  576. * @global WP_Query $wp_query WordPress Query object.
  577. *
  578. * @return bool
  579. */
  580. function is_robots() {
  581. global $wp_query;
  582. if ( ! isset( $wp_query ) ) {
  583. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  584. return false;
  585. }
  586. return $wp_query->is_robots();
  587. }
  588. /**
  589. * Is the query for the favicon.ico file?
  590. *
  591. * @since 5.4.0
  592. *
  593. * @global WP_Query $wp_query WordPress Query object.
  594. *
  595. * @return bool
  596. */
  597. function is_favicon() {
  598. global $wp_query;
  599. if ( ! isset( $wp_query ) ) {
  600. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  601. return false;
  602. }
  603. return $wp_query->is_favicon();
  604. }
  605. /**
  606. * Determines whether the query is for a search.
  607. *
  608. * For more information on this and similar theme functions, check out
  609. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  610. * Conditional Tags} article in the Theme Developer Handbook.
  611. *
  612. * @since 1.5.0
  613. *
  614. * @global WP_Query $wp_query WordPress Query object.
  615. *
  616. * @return bool
  617. */
  618. function is_search() {
  619. global $wp_query;
  620. if ( ! isset( $wp_query ) ) {
  621. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  622. return false;
  623. }
  624. return $wp_query->is_search();
  625. }
  626. /**
  627. * Determines whether the query is for an existing single post.
  628. *
  629. * Works for any post type, except attachments and pages
  630. *
  631. * If the $post parameter is specified, this function will additionally
  632. * check if the query is for one of the Posts specified.
  633. *
  634. * For more information on this and similar theme functions, check out
  635. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  636. * Conditional Tags} article in the Theme Developer Handbook.
  637. *
  638. * @see is_page()
  639. * @see is_singular()
  640. *
  641. * @since 1.5.0
  642. *
  643. * @global WP_Query $wp_query WordPress Query object.
  644. *
  645. * @param int|string|int[]|string[] $post Optional. Post ID, title, slug, or array of such
  646. * to check against. Default empty.
  647. * @return bool Whether the query is for an existing single post.
  648. */
  649. function is_single( $post = '' ) {
  650. global $wp_query;
  651. if ( ! isset( $wp_query ) ) {
  652. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  653. return false;
  654. }
  655. return $wp_query->is_single( $post );
  656. }
  657. /**
  658. * Determines whether the query is for an existing single post of any post type
  659. * (post, attachment, page, custom post types).
  660. *
  661. * If the $post_types parameter is specified, this function will additionally
  662. * check if the query is for one of the Posts Types specified.
  663. *
  664. * For more information on this and similar theme functions, check out
  665. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  666. * Conditional Tags} article in the Theme Developer Handbook.
  667. *
  668. * @see is_page()
  669. * @see is_single()
  670. *
  671. * @since 1.5.0
  672. *
  673. * @global WP_Query $wp_query WordPress Query object.
  674. *
  675. * @param string|string[] $post_types Optional. Post type or array of post types
  676. * to check against. Default empty.
  677. * @return bool Whether the query is for an existing single post
  678. * or any of the given post types.
  679. */
  680. function is_singular( $post_types = '' ) {
  681. global $wp_query;
  682. if ( ! isset( $wp_query ) ) {
  683. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  684. return false;
  685. }
  686. return $wp_query->is_singular( $post_types );
  687. }
  688. /**
  689. * Determines whether the query is for a specific time.
  690. *
  691. * For more information on this and similar theme functions, check out
  692. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  693. * Conditional Tags} article in the Theme Developer Handbook.
  694. *
  695. * @since 1.5.0
  696. *
  697. * @global WP_Query $wp_query WordPress Query object.
  698. *
  699. * @return bool
  700. */
  701. function is_time() {
  702. global $wp_query;
  703. if ( ! isset( $wp_query ) ) {
  704. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  705. return false;
  706. }
  707. return $wp_query->is_time();
  708. }
  709. /**
  710. * Determines whether the query is for a trackback endpoint call.
  711. *
  712. * For more information on this and similar theme functions, check out
  713. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  714. * Conditional Tags} article in the Theme Developer Handbook.
  715. *
  716. * @since 1.5.0
  717. *
  718. * @global WP_Query $wp_query WordPress Query object.
  719. *
  720. * @return bool
  721. */
  722. function is_trackback() {
  723. global $wp_query;
  724. if ( ! isset( $wp_query ) ) {
  725. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  726. return false;
  727. }
  728. return $wp_query->is_trackback();
  729. }
  730. /**
  731. * Determines whether the query is for an existing year archive.
  732. *
  733. * For more information on this and similar theme functions, check out
  734. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  735. * Conditional Tags} article in the Theme Developer Handbook.
  736. *
  737. * @since 1.5.0
  738. *
  739. * @global WP_Query $wp_query WordPress Query object.
  740. *
  741. * @return bool
  742. */
  743. function is_year() {
  744. global $wp_query;
  745. if ( ! isset( $wp_query ) ) {
  746. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  747. return false;
  748. }
  749. return $wp_query->is_year();
  750. }
  751. /**
  752. * Determines whether the query has resulted in a 404 (returns no results).
  753. *
  754. * For more information on this and similar theme functions, check out
  755. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  756. * Conditional Tags} article in the Theme Developer Handbook.
  757. *
  758. * @since 1.5.0
  759. *
  760. * @global WP_Query $wp_query WordPress Query object.
  761. *
  762. * @return bool
  763. */
  764. function is_404() {
  765. global $wp_query;
  766. if ( ! isset( $wp_query ) ) {
  767. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  768. return false;
  769. }
  770. return $wp_query->is_404();
  771. }
  772. /**
  773. * Is the query for an embedded post?
  774. *
  775. * @since 4.4.0
  776. *
  777. * @global WP_Query $wp_query WordPress Query object.
  778. *
  779. * @return bool Whether we're in an embedded post or not.
  780. */
  781. function is_embed() {
  782. global $wp_query;
  783. if ( ! isset( $wp_query ) ) {
  784. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  785. return false;
  786. }
  787. return $wp_query->is_embed();
  788. }
  789. /**
  790. * Determines whether the query is the main query.
  791. *
  792. * For more information on this and similar theme functions, check out
  793. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  794. * Conditional Tags} article in the Theme Developer Handbook.
  795. *
  796. * @since 3.3.0
  797. *
  798. * @global WP_Query $wp_query WordPress Query object.
  799. *
  800. * @return bool
  801. */
  802. function is_main_query() {
  803. if ( 'pre_get_posts' === current_filter() ) {
  804. $message = sprintf(
  805. /* translators: 1: pre_get_posts, 2: WP_Query->is_main_query(), 3: is_main_query(), 4: Link to codex is_main_query() page. */
  806. __( 'In %1$s, use the %2$s method, not the %3$s function. See %4$s.' ),
  807. '<code>pre_get_posts</code>',
  808. '<code>WP_Query->is_main_query()</code>',
  809. '<code>is_main_query()</code>',
  810. __( 'https://codex.wordpress.org/Function_Reference/is_main_query' )
  811. );
  812. _doing_it_wrong( __FUNCTION__, $message, '3.7.0' );
  813. }
  814. global $wp_query;
  815. return $wp_query->is_main_query();
  816. }
  817. /*
  818. * The Loop. Post loop control.
  819. */
  820. /**
  821. * Whether current WordPress query has results to loop over.
  822. *
  823. * @since 1.5.0
  824. *
  825. * @global WP_Query $wp_query WordPress Query object.
  826. *
  827. * @return bool
  828. */
  829. function have_posts() {
  830. global $wp_query;
  831. return $wp_query->have_posts();
  832. }
  833. /**
  834. * Determines whether the caller is in the Loop.
  835. *
  836. * For more information on this and similar theme functions, check out
  837. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  838. * Conditional Tags} article in the Theme Developer Handbook.
  839. *
  840. * @since 2.0.0
  841. *
  842. * @global WP_Query $wp_query WordPress Query object.
  843. *
  844. * @return bool True if caller is within loop, false if loop hasn't started or ended.
  845. */
  846. function in_the_loop() {
  847. global $wp_query;
  848. return $wp_query->in_the_loop;
  849. }
  850. /**
  851. * Rewind the loop posts.
  852. *
  853. * @since 1.5.0
  854. *
  855. * @global WP_Query $wp_query WordPress Query object.
  856. */
  857. function rewind_posts() {
  858. global $wp_query;
  859. $wp_query->rewind_posts();
  860. }
  861. /**
  862. * Iterate the post index in the loop.
  863. *
  864. * @since 1.5.0
  865. *
  866. * @global WP_Query $wp_query WordPress Query object.
  867. */
  868. function the_post() {
  869. global $wp_query;
  870. $wp_query->the_post();
  871. }
  872. /*
  873. * Comments loop.
  874. */
  875. /**
  876. * Whether there are comments to loop over.
  877. *
  878. * @since 2.2.0
  879. *
  880. * @global WP_Query $wp_query WordPress Query object.
  881. *
  882. * @return bool
  883. */
  884. function have_comments() {
  885. global $wp_query;
  886. return $wp_query->have_comments();
  887. }
  888. /**
  889. * Iterate comment index in the comment loop.
  890. *
  891. * @since 2.2.0
  892. *
  893. * @global WP_Query $wp_query WordPress Query object.
  894. *
  895. * @return object
  896. */
  897. function the_comment() {
  898. global $wp_query;
  899. return $wp_query->the_comment();
  900. }
  901. /**
  902. * Redirect old slugs to the correct permalink.
  903. *
  904. * Attempts to find the current slug from the past slugs.
  905. *
  906. * @since 2.1.0
  907. */
  908. function wp_old_slug_redirect() {
  909. if ( is_404() && '' !== get_query_var( 'name' ) ) {
  910. // Guess the current post type based on the query vars.
  911. if ( get_query_var( 'post_type' ) ) {
  912. $post_type = get_query_var( 'post_type' );
  913. } elseif ( get_query_var( 'attachment' ) ) {
  914. $post_type = 'attachment';
  915. } elseif ( get_query_var( 'pagename' ) ) {
  916. $post_type = 'page';
  917. } else {
  918. $post_type = 'post';
  919. }
  920. if ( is_array( $post_type ) ) {
  921. if ( count( $post_type ) > 1 ) {
  922. return;
  923. }
  924. $post_type = reset( $post_type );
  925. }
  926. // Do not attempt redirect for hierarchical post types.
  927. if ( is_post_type_hierarchical( $post_type ) ) {
  928. return;
  929. }
  930. $id = _find_post_by_old_slug( $post_type );
  931. if ( ! $id ) {
  932. $id = _find_post_by_old_date( $post_type );
  933. }
  934. /**
  935. * Filters the old slug redirect post ID.
  936. *
  937. * @since 4.9.3
  938. *
  939. * @param int $id The redirect post ID.
  940. */
  941. $id = apply_filters( 'old_slug_redirect_post_id', $id );
  942. if ( ! $id ) {
  943. return;
  944. }
  945. $link = get_permalink( $id );
  946. if ( get_query_var( 'paged' ) > 1 ) {
  947. $link = user_trailingslashit( trailingslashit( $link ) . 'page/' . get_query_var( 'paged' ) );
  948. } elseif ( is_embed() ) {
  949. $link = user_trailingslashit( trailingslashit( $link ) . 'embed' );
  950. }
  951. /**
  952. * Filters the old slug redirect URL.
  953. *
  954. * @since 4.4.0
  955. *
  956. * @param string $link The redirect URL.
  957. */
  958. $link = apply_filters( 'old_slug_redirect_url', $link );
  959. if ( ! $link ) {
  960. return;
  961. }
  962. wp_redirect( $link, 301 ); // Permanent redirect.
  963. exit;
  964. }
  965. }
  966. /**
  967. * Find the post ID for redirecting an old slug.
  968. *
  969. * @see wp_old_slug_redirect()
  970. *
  971. * @since 4.9.3
  972. * @access private
  973. *
  974. * @global wpdb $wpdb WordPress database abstraction object.
  975. *
  976. * @param string $post_type The current post type based on the query vars.
  977. * @return int $id The Post ID.
  978. */
  979. function _find_post_by_old_slug( $post_type ) {
  980. global $wpdb;
  981. $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, get_query_var( 'name' ) );
  982. // If year, monthnum, or day have been specified, make our query more precise
  983. // just in case there are multiple identical _wp_old_slug values.
  984. if ( get_query_var( 'year' ) ) {
  985. $query .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
  986. }
  987. if ( get_query_var( 'monthnum' ) ) {
  988. $query .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) );
  989. }
  990. if ( get_query_var( 'day' ) ) {
  991. $query .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
  992. }
  993. $id = (int) $wpdb->get_var( $query );
  994. return $id;
  995. }
  996. /**
  997. * Find the post ID for redirecting an old date.
  998. *
  999. * @see wp_old_slug_redirect()
  1000. *
  1001. * @since 4.9.3
  1002. * @access private
  1003. *
  1004. * @global wpdb $wpdb WordPress database abstraction object.
  1005. *
  1006. * @param string $post_type The current post type based on the query vars.
  1007. * @return int $id The Post ID.
  1008. */
  1009. function _find_post_by_old_date( $post_type ) {
  1010. global $wpdb;
  1011. $date_query = '';
  1012. if ( get_query_var( 'year' ) ) {
  1013. $date_query .= $wpdb->prepare( ' AND YEAR(pm_date.meta_value) = %d', get_query_var( 'year' ) );
  1014. }
  1015. if ( get_query_var( 'monthnum' ) ) {
  1016. $date_query .= $wpdb->prepare( ' AND MONTH(pm_date.meta_value) = %d', get_query_var( 'monthnum' ) );
  1017. }
  1018. if ( get_query_var( 'day' ) ) {
  1019. $date_query .= $wpdb->prepare( ' AND DAYOFMONTH(pm_date.meta_value) = %d', get_query_var( 'day' ) );
  1020. }
  1021. $id = 0;
  1022. if ( $date_query ) {
  1023. $id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta AS pm_date, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_date' AND post_name = %s" . $date_query, $post_type, get_query_var( 'name' ) ) );
  1024. if ( ! $id ) {
  1025. // Check to see if an old slug matches the old date.
  1026. $id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts, $wpdb->postmeta AS pm_slug, $wpdb->postmeta AS pm_date WHERE ID = pm_slug.post_id AND ID = pm_date.post_id AND post_type = %s AND pm_slug.meta_key = '_wp_old_slug' AND pm_slug.meta_value = %s AND pm_date.meta_key = '_wp_old_date'" . $date_query, $post_type, get_query_var( 'name' ) ) );
  1027. }
  1028. }
  1029. return $id;
  1030. }
  1031. /**
  1032. * Set up global post data.
  1033. *
  1034. * @since 1.5.0
  1035. * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  1036. *
  1037. * @global WP_Query $wp_query WordPress Query object.
  1038. *
  1039. * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  1040. * @return bool True when finished.
  1041. */
  1042. function setup_postdata( $post ) {
  1043. global $wp_query;
  1044. if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
  1045. return $wp_query->setup_postdata( $post );
  1046. }
  1047. return false;
  1048. }
  1049. /**
  1050. * Generates post data.
  1051. *
  1052. * @since 5.2.0
  1053. *
  1054. * @global WP_Query $wp_query WordPress Query object.
  1055. *
  1056. * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  1057. * @return array|bool Elements of post, or false on failure.
  1058. */
  1059. function generate_postdata( $post ) {
  1060. global $wp_query;
  1061. if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
  1062. return $wp_query->generate_postdata( $post );
  1063. }
  1064. return false;
  1065. }