query.php 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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 array List of post objects.
  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|array $post_types Optional. Post type or array of posts types to check against.
  163. * @return bool
  164. */
  165. function is_post_type_archive( $post_types = '' ) {
  166. global $wp_query;
  167. if ( ! isset( $wp_query ) ) {
  168. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  169. return false;
  170. }
  171. return $wp_query->is_post_type_archive( $post_types );
  172. }
  173. /**
  174. * Determines whether the query is for an existing attachment page.
  175. *
  176. * For more information on this and similar theme functions, check out
  177. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  178. * Conditional Tags} article in the Theme Developer Handbook.
  179. *
  180. * @since 2.0.0
  181. *
  182. * @global WP_Query $wp_query WordPress Query object.
  183. *
  184. * @param int|string|array|object $attachment Attachment ID, title, slug, or array of such.
  185. * @return bool
  186. */
  187. function is_attachment( $attachment = '' ) {
  188. global $wp_query;
  189. if ( ! isset( $wp_query ) ) {
  190. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  191. return false;
  192. }
  193. return $wp_query->is_attachment( $attachment );
  194. }
  195. /**
  196. * Determines whether the query is for an existing author archive page.
  197. *
  198. * If the $author parameter is specified, this function will additionally
  199. * check if the query is for one of the authors specified.
  200. *
  201. * For more information on this and similar theme functions, check out
  202. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  203. * Conditional Tags} article in the Theme Developer Handbook.
  204. *
  205. * @since 1.5.0
  206. *
  207. * @global WP_Query $wp_query WordPress Query object.
  208. *
  209. * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  210. * @return bool
  211. */
  212. function is_author( $author = '' ) {
  213. global $wp_query;
  214. if ( ! isset( $wp_query ) ) {
  215. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  216. return false;
  217. }
  218. return $wp_query->is_author( $author );
  219. }
  220. /**
  221. * Determines whether the query is for an existing category archive page.
  222. *
  223. * If the $category parameter is specified, this function will additionally
  224. * check if the query is for one of the categories specified.
  225. *
  226. * For more information on this and similar theme functions, check out
  227. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  228. * Conditional Tags} article in the Theme Developer Handbook.
  229. *
  230. * @since 1.5.0
  231. *
  232. * @global WP_Query $wp_query WordPress Query object.
  233. *
  234. * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  235. * @return bool
  236. */
  237. function is_category( $category = '' ) {
  238. global $wp_query;
  239. if ( ! isset( $wp_query ) ) {
  240. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  241. return false;
  242. }
  243. return $wp_query->is_category( $category );
  244. }
  245. /**
  246. * Determines whether the query is for an existing tag archive page.
  247. *
  248. * If the $tag parameter is specified, this function will additionally
  249. * check if the query is for one of the tags specified.
  250. *
  251. * For more information on this and similar theme functions, check out
  252. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  253. * Conditional Tags} article in the Theme Developer Handbook.
  254. *
  255. * @since 2.3.0
  256. *
  257. * @global WP_Query $wp_query WordPress Query object.
  258. *
  259. * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  260. * @return bool
  261. */
  262. function is_tag( $tag = '' ) {
  263. global $wp_query;
  264. if ( ! isset( $wp_query ) ) {
  265. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  266. return false;
  267. }
  268. return $wp_query->is_tag( $tag );
  269. }
  270. /**
  271. * Determines whether the query is for an existing custom taxonomy archive page.
  272. *
  273. * If the $taxonomy parameter is specified, this function will additionally
  274. * check if the query is for that specific $taxonomy.
  275. *
  276. * If the $term parameter is specified in addition to the $taxonomy parameter,
  277. * this function will additionally check if the query is for one of the terms
  278. * specified.
  279. *
  280. * For more information on this and similar theme functions, check out
  281. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  282. * Conditional Tags} article in the Theme Developer Handbook.
  283. *
  284. * @since 2.5.0
  285. *
  286. * @global WP_Query $wp_query WordPress Query object.
  287. *
  288. * @param string|array $taxonomy Optional. Taxonomy slug or slugs.
  289. * @param int|string|array $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
  290. * @return bool True for custom taxonomy archive pages, false for built-in taxonomies (category and tag archives).
  291. */
  292. function is_tax( $taxonomy = '', $term = '' ) {
  293. global $wp_query;
  294. if ( ! isset( $wp_query ) ) {
  295. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  296. return false;
  297. }
  298. return $wp_query->is_tax( $taxonomy, $term );
  299. }
  300. /**
  301. * Determines whether the query is for an existing date archive.
  302. *
  303. * For more information on this and similar theme functions, check out
  304. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  305. * Conditional Tags} article in the Theme Developer Handbook.
  306. *
  307. * @since 1.5.0
  308. *
  309. * @global WP_Query $wp_query WordPress Query object.
  310. *
  311. * @return bool
  312. */
  313. function is_date() {
  314. global $wp_query;
  315. if ( ! isset( $wp_query ) ) {
  316. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  317. return false;
  318. }
  319. return $wp_query->is_date();
  320. }
  321. /**
  322. * Determines whether the query is for an existing day archive.
  323. *
  324. * A conditional check to test whether the page is a date-based archive page displaying posts for the current day.
  325. *
  326. * For more information on this and similar theme functions, check out
  327. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  328. * Conditional Tags} article in the Theme Developer Handbook.
  329. *
  330. * @since 1.5.0
  331. *
  332. * @global WP_Query $wp_query WordPress Query object.
  333. *
  334. * @return bool
  335. */
  336. function is_day() {
  337. global $wp_query;
  338. if ( ! isset( $wp_query ) ) {
  339. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  340. return false;
  341. }
  342. return $wp_query->is_day();
  343. }
  344. /**
  345. * Determines whether the query is for a feed.
  346. *
  347. * For more information on this and similar theme functions, check out
  348. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  349. * Conditional Tags} article in the Theme Developer Handbook.
  350. *
  351. * @since 1.5.0
  352. *
  353. * @global WP_Query $wp_query WordPress Query object.
  354. *
  355. * @param string|array $feeds Optional feed types to check.
  356. * @return bool
  357. */
  358. function is_feed( $feeds = '' ) {
  359. global $wp_query;
  360. if ( ! isset( $wp_query ) ) {
  361. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  362. return false;
  363. }
  364. return $wp_query->is_feed( $feeds );
  365. }
  366. /**
  367. * Is the query for a comments feed?
  368. *
  369. * @since 3.0.0
  370. *
  371. * @global WP_Query $wp_query WordPress Query object.
  372. *
  373. * @return bool
  374. */
  375. function is_comment_feed() {
  376. global $wp_query;
  377. if ( ! isset( $wp_query ) ) {
  378. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  379. return false;
  380. }
  381. return $wp_query->is_comment_feed();
  382. }
  383. /**
  384. * Determines whether the query is for the front page of the site.
  385. *
  386. * This is for what is displayed at your site's main URL.
  387. *
  388. * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
  389. *
  390. * If you set a static page for the front page of your site, this function will return
  391. * true when viewing that page.
  392. *
  393. * Otherwise the same as @see is_home()
  394. *
  395. * For more information on this and similar theme functions, check out
  396. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  397. * Conditional Tags} article in the Theme Developer Handbook.
  398. *
  399. * @since 2.5.0
  400. *
  401. * @global WP_Query $wp_query WordPress Query object.
  402. *
  403. * @return bool True, if front of site.
  404. */
  405. function is_front_page() {
  406. global $wp_query;
  407. if ( ! isset( $wp_query ) ) {
  408. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  409. return false;
  410. }
  411. return $wp_query->is_front_page();
  412. }
  413. /**
  414. * Determines whether the query is for the blog homepage.
  415. *
  416. * The blog homepage is the page that shows the time-based blog content of the site.
  417. *
  418. * is_home() is dependent on the site's "Front page displays" Reading Settings 'show_on_front'
  419. * and 'page_for_posts'.
  420. *
  421. * If a static page is set for the front page of the site, this function will return true only
  422. * on the page you set as the "Posts page".
  423. *
  424. * For more information on this and similar theme functions, check out
  425. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  426. * Conditional Tags} article in the Theme Developer Handbook.
  427. *
  428. * @since 1.5.0
  429. *
  430. * @see is_front_page()
  431. * @global WP_Query $wp_query WordPress Query object.
  432. *
  433. * @return bool True if blog view homepage, otherwise false.
  434. */
  435. function is_home() {
  436. global $wp_query;
  437. if ( ! isset( $wp_query ) ) {
  438. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  439. return false;
  440. }
  441. return $wp_query->is_home();
  442. }
  443. /**
  444. * Determines whether the query is for the Privacy Policy page.
  445. *
  446. * The Privacy Policy page is the page that shows the Privacy Policy content of the site.
  447. *
  448. * is_privacy_policy() is dependent on the site's "Change your Privacy Policy page" Privacy Settings 'wp_page_for_privacy_policy'.
  449. *
  450. * This function will return true only on the page you set as the "Privacy Policy page".
  451. *
  452. * For more information on this and similar theme functions, check out
  453. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  454. * Conditional Tags} article in the Theme Developer Handbook.
  455. *
  456. * @since 5.2.0
  457. *
  458. * @global WP_Query $wp_query WordPress Query object.
  459. *
  460. * @return bool
  461. */
  462. function is_privacy_policy() {
  463. global $wp_query;
  464. if ( ! isset( $wp_query ) ) {
  465. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  466. return false;
  467. }
  468. return $wp_query->is_privacy_policy();
  469. }
  470. /**
  471. * Determines whether the query is for an existing month archive.
  472. *
  473. * For more information on this and similar theme functions, check out
  474. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  475. * Conditional Tags} article in the Theme Developer Handbook.
  476. *
  477. * @since 1.5.0
  478. *
  479. * @global WP_Query $wp_query WordPress Query object.
  480. *
  481. * @return bool
  482. */
  483. function is_month() {
  484. global $wp_query;
  485. if ( ! isset( $wp_query ) ) {
  486. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  487. return false;
  488. }
  489. return $wp_query->is_month();
  490. }
  491. /**
  492. * Determines whether the query is for an existing single page.
  493. *
  494. * If the $page parameter is specified, this function will additionally
  495. * check if the query is for one of the pages specified.
  496. *
  497. * For more information on this and similar theme functions, check out
  498. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  499. * Conditional Tags} article in the Theme Developer Handbook.
  500. *
  501. * @see is_single()
  502. * @see is_singular()
  503. *
  504. * @since 1.5.0
  505. *
  506. * @global WP_Query $wp_query WordPress Query object.
  507. *
  508. * @param int|string|array $page Optional. Page ID, title, slug, or array of such. Default empty.
  509. * @return bool Whether the query is for an existing single page.
  510. */
  511. function is_page( $page = '' ) {
  512. global $wp_query;
  513. if ( ! isset( $wp_query ) ) {
  514. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  515. return false;
  516. }
  517. return $wp_query->is_page( $page );
  518. }
  519. /**
  520. * Determines whether the query is for paged results and not for the first page.
  521. *
  522. * For more information on this and similar theme functions, check out
  523. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  524. * Conditional Tags} article in the Theme Developer Handbook.
  525. *
  526. * @since 1.5.0
  527. *
  528. * @global WP_Query $wp_query WordPress Query object.
  529. *
  530. * @return bool
  531. */
  532. function is_paged() {
  533. global $wp_query;
  534. if ( ! isset( $wp_query ) ) {
  535. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  536. return false;
  537. }
  538. return $wp_query->is_paged();
  539. }
  540. /**
  541. * Determines whether the query is for a post or page preview.
  542. *
  543. * For more information on this and similar theme functions, check out
  544. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  545. * Conditional Tags} article in the Theme Developer Handbook.
  546. *
  547. * @since 2.0.0
  548. *
  549. * @global WP_Query $wp_query WordPress Query object.
  550. *
  551. * @return bool
  552. */
  553. function is_preview() {
  554. global $wp_query;
  555. if ( ! isset( $wp_query ) ) {
  556. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  557. return false;
  558. }
  559. return $wp_query->is_preview();
  560. }
  561. /**
  562. * Is the query for the robots file?
  563. *
  564. * @since 2.1.0
  565. *
  566. * @global WP_Query $wp_query WordPress Query object.
  567. *
  568. * @return bool
  569. */
  570. function is_robots() {
  571. global $wp_query;
  572. if ( ! isset( $wp_query ) ) {
  573. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  574. return false;
  575. }
  576. return $wp_query->is_robots();
  577. }
  578. /**
  579. * Determines whether the query is for a search.
  580. *
  581. * For more information on this and similar theme functions, check out
  582. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  583. * Conditional Tags} article in the Theme Developer Handbook.
  584. *
  585. * @since 1.5.0
  586. *
  587. * @global WP_Query $wp_query WordPress Query object.
  588. *
  589. * @return bool
  590. */
  591. function is_search() {
  592. global $wp_query;
  593. if ( ! isset( $wp_query ) ) {
  594. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  595. return false;
  596. }
  597. return $wp_query->is_search();
  598. }
  599. /**
  600. * Determines whether the query is for an existing single post.
  601. *
  602. * Works for any post type, except attachments and pages
  603. *
  604. * If the $post parameter is specified, this function will additionally
  605. * check if the query is for one of the Posts specified.
  606. *
  607. * For more information on this and similar theme functions, check out
  608. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  609. * Conditional Tags} article in the Theme Developer Handbook.
  610. *
  611. * @see is_page()
  612. * @see is_singular()
  613. *
  614. * @since 1.5.0
  615. *
  616. * @global WP_Query $wp_query WordPress Query object.
  617. *
  618. * @param int|string|array $post Optional. Post ID, title, slug, or array of such. Default empty.
  619. * @return bool Whether the query is for an existing single post.
  620. */
  621. function is_single( $post = '' ) {
  622. global $wp_query;
  623. if ( ! isset( $wp_query ) ) {
  624. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  625. return false;
  626. }
  627. return $wp_query->is_single( $post );
  628. }
  629. /**
  630. * Determines whether the query is for an existing single post of any post type
  631. * (post, attachment, page, custom post types).
  632. *
  633. * If the $post_types parameter is specified, this function will additionally
  634. * check if the query is for one of the Posts Types specified.
  635. *
  636. * For more information on this and similar theme functions, check out
  637. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  638. * Conditional Tags} article in the Theme Developer Handbook.
  639. *
  640. * @see is_page()
  641. * @see is_single()
  642. *
  643. * @since 1.5.0
  644. *
  645. * @global WP_Query $wp_query WordPress Query object.
  646. *
  647. * @param string|array $post_types Optional. Post type or array of post types. Default empty.
  648. * @return bool Whether the query is for an existing single post of any of the given post types.
  649. */
  650. function is_singular( $post_types = '' ) {
  651. global $wp_query;
  652. if ( ! isset( $wp_query ) ) {
  653. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  654. return false;
  655. }
  656. return $wp_query->is_singular( $post_types );
  657. }
  658. /**
  659. * Determines whether the query is for a specific time.
  660. *
  661. * For more information on this and similar theme functions, check out
  662. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  663. * Conditional Tags} article in the Theme Developer Handbook.
  664. *
  665. * @since 1.5.0
  666. *
  667. * @global WP_Query $wp_query WordPress Query object.
  668. *
  669. * @return bool
  670. */
  671. function is_time() {
  672. global $wp_query;
  673. if ( ! isset( $wp_query ) ) {
  674. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  675. return false;
  676. }
  677. return $wp_query->is_time();
  678. }
  679. /**
  680. * Determines whether the query is for a trackback endpoint call.
  681. *
  682. * For more information on this and similar theme functions, check out
  683. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  684. * Conditional Tags} article in the Theme Developer Handbook.
  685. *
  686. * @since 1.5.0
  687. *
  688. * @global WP_Query $wp_query WordPress Query object.
  689. *
  690. * @return bool
  691. */
  692. function is_trackback() {
  693. global $wp_query;
  694. if ( ! isset( $wp_query ) ) {
  695. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  696. return false;
  697. }
  698. return $wp_query->is_trackback();
  699. }
  700. /**
  701. * Determines whether the query is for an existing year archive.
  702. *
  703. * For more information on this and similar theme functions, check out
  704. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  705. * Conditional Tags} article in the Theme Developer Handbook.
  706. *
  707. * @since 1.5.0
  708. *
  709. * @global WP_Query $wp_query WordPress Query object.
  710. *
  711. * @return bool
  712. */
  713. function is_year() {
  714. global $wp_query;
  715. if ( ! isset( $wp_query ) ) {
  716. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  717. return false;
  718. }
  719. return $wp_query->is_year();
  720. }
  721. /**
  722. * Determines whether the query has resulted in a 404 (returns no results).
  723. *
  724. * For more information on this and similar theme functions, check out
  725. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  726. * Conditional Tags} article in the Theme Developer Handbook.
  727. *
  728. * @since 1.5.0
  729. *
  730. * @global WP_Query $wp_query WordPress Query object.
  731. *
  732. * @return bool
  733. */
  734. function is_404() {
  735. global $wp_query;
  736. if ( ! isset( $wp_query ) ) {
  737. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  738. return false;
  739. }
  740. return $wp_query->is_404();
  741. }
  742. /**
  743. * Is the query for an embedded post?
  744. *
  745. * @since 4.4.0
  746. *
  747. * @global WP_Query $wp_query WordPress Query object.
  748. *
  749. * @return bool Whether we're in an embedded post or not.
  750. */
  751. function is_embed() {
  752. global $wp_query;
  753. if ( ! isset( $wp_query ) ) {
  754. _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
  755. return false;
  756. }
  757. return $wp_query->is_embed();
  758. }
  759. /**
  760. * Determines whether the query is the main query.
  761. *
  762. * For more information on this and similar theme functions, check out
  763. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  764. * Conditional Tags} article in the Theme Developer Handbook.
  765. *
  766. * @since 3.3.0
  767. *
  768. * @global WP_Query $wp_query WordPress Query object.
  769. *
  770. * @return bool
  771. */
  772. function is_main_query() {
  773. if ( 'pre_get_posts' === current_filter() ) {
  774. $message = sprintf(
  775. /* translators: 1: pre_get_posts, 2: WP_Query->is_main_query(), 3: is_main_query(), 4: Link to codex is_main_query() page. */
  776. __( 'In %1$s, use the %2$s method, not the %3$s function. See %4$s.' ),
  777. '<code>pre_get_posts</code>',
  778. '<code>WP_Query->is_main_query()</code>',
  779. '<code>is_main_query()</code>',
  780. __( 'https://codex.wordpress.org/Function_Reference/is_main_query' )
  781. );
  782. _doing_it_wrong( __FUNCTION__, $message, '3.7.0' );
  783. }
  784. global $wp_query;
  785. return $wp_query->is_main_query();
  786. }
  787. /*
  788. * The Loop. Post loop control.
  789. */
  790. /**
  791. * Whether current WordPress query has results to loop over.
  792. *
  793. * @since 1.5.0
  794. *
  795. * @global WP_Query $wp_query WordPress Query object.
  796. *
  797. * @return bool
  798. */
  799. function have_posts() {
  800. global $wp_query;
  801. return $wp_query->have_posts();
  802. }
  803. /**
  804. * Determines whether the caller is in the Loop.
  805. *
  806. * For more information on this and similar theme functions, check out
  807. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  808. * Conditional Tags} article in the Theme Developer Handbook.
  809. *
  810. * @since 2.0.0
  811. *
  812. * @global WP_Query $wp_query WordPress Query object.
  813. *
  814. * @return bool True if caller is within loop, false if loop hasn't started or ended.
  815. */
  816. function in_the_loop() {
  817. global $wp_query;
  818. return $wp_query->in_the_loop;
  819. }
  820. /**
  821. * Rewind the loop posts.
  822. *
  823. * @since 1.5.0
  824. *
  825. * @global WP_Query $wp_query WordPress Query object.
  826. */
  827. function rewind_posts() {
  828. global $wp_query;
  829. $wp_query->rewind_posts();
  830. }
  831. /**
  832. * Iterate the post index in the loop.
  833. *
  834. * @since 1.5.0
  835. *
  836. * @global WP_Query $wp_query WordPress Query object.
  837. */
  838. function the_post() {
  839. global $wp_query;
  840. $wp_query->the_post();
  841. }
  842. /*
  843. * Comments loop.
  844. */
  845. /**
  846. * Whether there are comments to loop over.
  847. *
  848. * @since 2.2.0
  849. *
  850. * @global WP_Query $wp_query WordPress Query object.
  851. *
  852. * @return bool
  853. */
  854. function have_comments() {
  855. global $wp_query;
  856. return $wp_query->have_comments();
  857. }
  858. /**
  859. * Iterate comment index in the comment loop.
  860. *
  861. * @since 2.2.0
  862. *
  863. * @global WP_Query $wp_query WordPress Query object.
  864. *
  865. * @return object
  866. */
  867. function the_comment() {
  868. global $wp_query;
  869. return $wp_query->the_comment();
  870. }
  871. /**
  872. * Redirect old slugs to the correct permalink.
  873. *
  874. * Attempts to find the current slug from the past slugs.
  875. *
  876. * @since 2.1.0
  877. */
  878. function wp_old_slug_redirect() {
  879. if ( is_404() && '' !== get_query_var( 'name' ) ) {
  880. // Guess the current post_type based on the query vars.
  881. if ( get_query_var( 'post_type' ) ) {
  882. $post_type = get_query_var( 'post_type' );
  883. } elseif ( get_query_var( 'attachment' ) ) {
  884. $post_type = 'attachment';
  885. } elseif ( get_query_var( 'pagename' ) ) {
  886. $post_type = 'page';
  887. } else {
  888. $post_type = 'post';
  889. }
  890. if ( is_array( $post_type ) ) {
  891. if ( count( $post_type ) > 1 ) {
  892. return;
  893. }
  894. $post_type = reset( $post_type );
  895. }
  896. // Do not attempt redirect for hierarchical post types
  897. if ( is_post_type_hierarchical( $post_type ) ) {
  898. return;
  899. }
  900. $id = _find_post_by_old_slug( $post_type );
  901. if ( ! $id ) {
  902. $id = _find_post_by_old_date( $post_type );
  903. }
  904. /**
  905. * Filters the old slug redirect post ID.
  906. *
  907. * @since 4.9.3
  908. *
  909. * @param int $id The redirect post ID.
  910. */
  911. $id = apply_filters( 'old_slug_redirect_post_id', $id );
  912. if ( ! $id ) {
  913. return;
  914. }
  915. $link = get_permalink( $id );
  916. if ( get_query_var( 'paged' ) > 1 ) {
  917. $link = user_trailingslashit( trailingslashit( $link ) . 'page/' . get_query_var( 'paged' ) );
  918. } elseif ( is_embed() ) {
  919. $link = user_trailingslashit( trailingslashit( $link ) . 'embed' );
  920. }
  921. /**
  922. * Filters the old slug redirect URL.
  923. *
  924. * @since 4.4.0
  925. *
  926. * @param string $link The redirect URL.
  927. */
  928. $link = apply_filters( 'old_slug_redirect_url', $link );
  929. if ( ! $link ) {
  930. return;
  931. }
  932. wp_redirect( $link, 301 ); // Permanent redirect
  933. exit;
  934. }
  935. }
  936. /**
  937. * Find the post ID for redirecting an old slug.
  938. *
  939. * @see wp_old_slug_redirect()
  940. *
  941. * @since 4.9.3
  942. * @access private
  943. *
  944. * @global wpdb $wpdb WordPress database abstraction object.
  945. *
  946. * @param string $post_type The current post type based on the query vars.
  947. * @return int $id The Post ID.
  948. */
  949. function _find_post_by_old_slug( $post_type ) {
  950. global $wpdb;
  951. $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' ) );
  952. // if year, monthnum, or day have been specified, make our query more precise
  953. // just in case there are multiple identical _wp_old_slug values
  954. if ( get_query_var( 'year' ) ) {
  955. $query .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
  956. }
  957. if ( get_query_var( 'monthnum' ) ) {
  958. $query .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) );
  959. }
  960. if ( get_query_var( 'day' ) ) {
  961. $query .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
  962. }
  963. $id = (int) $wpdb->get_var( $query );
  964. return $id;
  965. }
  966. /**
  967. * Find the post ID for redirecting an old date.
  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_date( $post_type ) {
  980. global $wpdb;
  981. $date_query = '';
  982. if ( get_query_var( 'year' ) ) {
  983. $date_query .= $wpdb->prepare( ' AND YEAR(pm_date.meta_value) = %d', get_query_var( 'year' ) );
  984. }
  985. if ( get_query_var( 'monthnum' ) ) {
  986. $date_query .= $wpdb->prepare( ' AND MONTH(pm_date.meta_value) = %d', get_query_var( 'monthnum' ) );
  987. }
  988. if ( get_query_var( 'day' ) ) {
  989. $date_query .= $wpdb->prepare( ' AND DAYOFMONTH(pm_date.meta_value) = %d', get_query_var( 'day' ) );
  990. }
  991. $id = 0;
  992. if ( $date_query ) {
  993. $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' ) ) );
  994. if ( ! $id ) {
  995. // Check to see if an old slug matches the old date
  996. $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' ) ) );
  997. }
  998. }
  999. return $id;
  1000. }
  1001. /**
  1002. * Set up global post data.
  1003. *
  1004. * @since 1.5.0
  1005. * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  1006. *
  1007. * @global WP_Query $wp_query WordPress Query object.
  1008. *
  1009. * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  1010. * @return bool True when finished.
  1011. */
  1012. function setup_postdata( $post ) {
  1013. global $wp_query;
  1014. if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
  1015. return $wp_query->setup_postdata( $post );
  1016. }
  1017. return false;
  1018. }
  1019. /**
  1020. * Generates post data.
  1021. *
  1022. * @since 5.2.0
  1023. *
  1024. * @global WP_Query $wp_query WordPress Query object.
  1025. *
  1026. * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  1027. * @return array|bool Elements of post, or false on failure.
  1028. */
  1029. function generate_postdata( $post ) {
  1030. global $wp_query;
  1031. if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
  1032. return $wp_query->generate_postdata( $post );
  1033. }
  1034. return false;
  1035. }