PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-includes/post-template.php

https://gitlab.com/endomorphosis/reservationtelco
PHP | 1236 lines | 654 code | 165 blank | 417 comment | 194 complexity | 8bc64aceacd73527d7de5f1c6c573225 MD5 | raw file
  1. <?php
  2. /**
  3. * WordPress Post Template Functions.
  4. *
  5. * Gets content for the current post in the loop.
  6. *
  7. * @package WordPress
  8. * @subpackage Template
  9. */
  10. /**
  11. * Display the ID of the current item in the WordPress Loop.
  12. *
  13. * @since 0.71
  14. * @uses $id
  15. */
  16. function the_ID() {
  17. global $id;
  18. echo $id;
  19. }
  20. /**
  21. * Retrieve the ID of the current item in the WordPress Loop.
  22. *
  23. * @since 2.1.0
  24. * @uses $id
  25. *
  26. * @return unknown
  27. */
  28. function get_the_ID() {
  29. global $id;
  30. return $id;
  31. }
  32. /**
  33. * Display or retrieve the current post title with optional content.
  34. *
  35. * @since 0.71
  36. *
  37. * @param string $before Optional. Content to prepend to the title.
  38. * @param string $after Optional. Content to append to the title.
  39. * @param bool $echo Optional, default to true.Whether to display or return.
  40. * @return null|string Null on no title. String if $echo parameter is false.
  41. */
  42. function the_title($before = '', $after = '', $echo = true) {
  43. $title = get_the_title();
  44. if ( strlen($title) == 0 )
  45. return;
  46. $title = $before . $title . $after;
  47. if ( $echo )
  48. echo $title;
  49. else
  50. return $title;
  51. }
  52. /**
  53. * Sanitize the current title when retrieving or displaying.
  54. *
  55. * Works like {@link the_title()}, except the parameters can be in a string or
  56. * an array. See the function for what can be override in the $args parameter.
  57. *
  58. * The title before it is displayed will have the tags stripped and {@link
  59. * esc_attr()} before it is passed to the user or displayed. The default
  60. * as with {@link the_title()}, is to display the title.
  61. *
  62. * @since 2.3.0
  63. *
  64. * @param string|array $args Optional. Override the defaults.
  65. * @return string|null Null on failure or display. String when echo is false.
  66. */
  67. function the_title_attribute( $args = '' ) {
  68. $title = get_the_title();
  69. if ( strlen($title) == 0 )
  70. return;
  71. $defaults = array('before' => '', 'after' => '', 'echo' => true);
  72. $r = wp_parse_args($args, $defaults);
  73. extract( $r, EXTR_SKIP );
  74. $title = $before . $title . $after;
  75. $title = esc_attr(strip_tags($title));
  76. if ( $echo )
  77. echo $title;
  78. else
  79. return $title;
  80. }
  81. /**
  82. * Retrieve post title.
  83. *
  84. * If the post is protected and the visitor is not an admin, then "Protected"
  85. * will be displayed before the post title. If the post is private, then
  86. * "Private" will be located before the post title.
  87. *
  88. * @since 0.71
  89. *
  90. * @param int $id Optional. Post ID.
  91. * @return string
  92. */
  93. function get_the_title( $id = 0 ) {
  94. $post = &get_post($id);
  95. $title = isset($post->post_title) ? $post->post_title : '';
  96. $id = isset($post->ID) ? $post->ID : (int) $id;
  97. if ( !is_admin() ) {
  98. if ( !empty($post->post_password) ) {
  99. $protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
  100. $title = sprintf($protected_title_format, $title);
  101. } else if ( isset($post->post_status) && 'private' == $post->post_status ) {
  102. $private_title_format = apply_filters('private_title_format', __('Private: %s'));
  103. $title = sprintf($private_title_format, $title);
  104. }
  105. }
  106. return apply_filters( 'the_title', $title, $id );
  107. }
  108. /**
  109. * Display the Post Global Unique Identifier (guid).
  110. *
  111. * The guid will appear to be a link, but should not be used as an link to the
  112. * post. The reason you should not use it as a link, is because of moving the
  113. * blog across domains.
  114. *
  115. * Url is escaped to make it xml safe
  116. *
  117. * @since 1.5.0
  118. *
  119. * @param int $id Optional. Post ID.
  120. */
  121. function the_guid( $id = 0 ) {
  122. echo esc_url( get_the_guid($id) );
  123. }
  124. /**
  125. * Retrieve the Post Global Unique Identifier (guid).
  126. *
  127. * The guid will appear to be a link, but should not be used as an link to the
  128. * post. The reason you should not use it as a link, is because of moving the
  129. * blog across domains.
  130. *
  131. * @since 1.5.0
  132. *
  133. * @param int $id Optional. Post ID.
  134. * @return string
  135. */
  136. function get_the_guid( $id = 0 ) {
  137. $post = &get_post($id);
  138. return apply_filters('get_the_guid', $post->guid);
  139. }
  140. /**
  141. * Display the post content.
  142. *
  143. * @since 0.71
  144. *
  145. * @param string $more_link_text Optional. Content for when there is more text.
  146. * @param string $stripteaser Optional. Teaser content before the more text.
  147. */
  148. function the_content($more_link_text = null, $stripteaser = 0) {
  149. $content = get_the_content($more_link_text, $stripteaser);
  150. $content = apply_filters('the_content', $content);
  151. $content = str_replace(']]>', ']]&gt;', $content);
  152. echo $content;
  153. }
  154. /**
  155. * Retrieve the post content.
  156. *
  157. * @since 0.71
  158. *
  159. * @param string $more_link_text Optional. Content for when there is more text.
  160. * @param string $stripteaser Optional. Teaser content before the more text.
  161. * @return string
  162. */
  163. function get_the_content($more_link_text = null, $stripteaser = 0) {
  164. global $id, $post, $more, $page, $pages, $multipage, $preview;
  165. if ( null === $more_link_text )
  166. $more_link_text = __( '(more...)' );
  167. $output = '';
  168. $hasTeaser = false;
  169. // If post password required and it doesn't match the cookie.
  170. if ( post_password_required($post) ) {
  171. $output = get_the_password_form();
  172. return $output;
  173. }
  174. if ( $page > count($pages) ) // if the requested page doesn't exist
  175. $page = count($pages); // give them the highest numbered page that DOES exist
  176. $content = $pages[$page-1];
  177. if ( preg_match('/<!--more(.*?)?-->/', $content, $matches) ) {
  178. $content = explode($matches[0], $content, 2);
  179. if ( !empty($matches[1]) && !empty($more_link_text) )
  180. $more_link_text = strip_tags(wp_kses_no_null(trim($matches[1])));
  181. $hasTeaser = true;
  182. } else {
  183. $content = array($content);
  184. }
  185. if ( (false !== strpos($post->post_content, '<!--noteaser-->') && ((!$multipage) || ($page==1))) )
  186. $stripteaser = 1;
  187. $teaser = $content[0];
  188. if ( ($more) && ($stripteaser) && ($hasTeaser) )
  189. $teaser = '';
  190. $output .= $teaser;
  191. if ( count($content) > 1 ) {
  192. if ( $more ) {
  193. $output .= '<span id="more-' . $id . '"></span>' . $content[1];
  194. } else {
  195. if ( ! empty($more_link_text) )
  196. $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-$id\" class=\"more-link\">$more_link_text</a>", $more_link_text );
  197. $output = force_balance_tags($output);
  198. }
  199. }
  200. if ( $preview ) // preview fix for javascript bug with foreign languages
  201. $output = preg_replace_callback('/\%u([0-9A-F]{4})/', create_function('$match', 'return "&#" . base_convert($match[1], 16, 10) . ";";'), $output);
  202. return $output;
  203. }
  204. /**
  205. * Display the post excerpt.
  206. *
  207. * @since 0.71
  208. * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
  209. */
  210. function the_excerpt() {
  211. echo apply_filters('the_excerpt', get_the_excerpt());
  212. }
  213. /**
  214. * Retrieve the post excerpt.
  215. *
  216. * @since 0.71
  217. *
  218. * @param mixed $deprecated Not used.
  219. * @return string
  220. */
  221. function get_the_excerpt( $deprecated = '' ) {
  222. if ( !empty( $deprecated ) )
  223. _deprecated_argument( __FUNCTION__, '2.3' );
  224. global $post;
  225. $output = $post->post_excerpt;
  226. if ( post_password_required($post) ) {
  227. $output = __('There is no excerpt because this is a protected post.');
  228. return $output;
  229. }
  230. return apply_filters('get_the_excerpt', $output);
  231. }
  232. /**
  233. * Whether post has excerpt.
  234. *
  235. * @since 2.3.0
  236. *
  237. * @param int $id Optional. Post ID.
  238. * @return bool
  239. */
  240. function has_excerpt( $id = 0 ) {
  241. $post = &get_post( $id );
  242. return ( !empty( $post->post_excerpt ) );
  243. }
  244. /**
  245. * Display the classes for the post div.
  246. *
  247. * @since 2.7.0
  248. *
  249. * @param string|array $class One or more classes to add to the class list.
  250. * @param int $post_id An optional post ID.
  251. */
  252. function post_class( $class = '', $post_id = null ) {
  253. // Separates classes with a single space, collates classes for post DIV
  254. echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
  255. }
  256. /**
  257. * Retrieve the classes for the post div as an array.
  258. *
  259. * The class names are add are many. If the post is a sticky, then the 'sticky'
  260. * class name. The class 'hentry' is always added to each post. For each
  261. * category, the class will be added with 'category-' with category slug is
  262. * added. The tags are the same way as the categories with 'tag-' before the tag
  263. * slug. All classes are passed through the filter, 'post_class' with the list
  264. * of classes, followed by $class parameter value, with the post ID as the last
  265. * parameter.
  266. *
  267. * @since 2.7.0
  268. *
  269. * @param string|array $class One or more classes to add to the class list.
  270. * @param int $post_id An optional post ID.
  271. * @return array Array of classes.
  272. */
  273. function get_post_class( $class = '', $post_id = null ) {
  274. $post = get_post($post_id);
  275. $classes = array();
  276. if ( empty($post) )
  277. return $classes;
  278. $classes[] = 'post-' . $post->ID;
  279. $classes[] = $post->post_type;
  280. $classes[] = 'type-' . $post->post_type;
  281. // sticky for Sticky Posts
  282. if ( is_sticky($post->ID) && is_home() && !is_paged() )
  283. $classes[] = 'sticky';
  284. // hentry for hAtom compliace
  285. $classes[] = 'hentry';
  286. // Categories
  287. foreach ( (array) get_the_category($post->ID) as $cat ) {
  288. if ( empty($cat->slug ) )
  289. continue;
  290. $classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->cat_ID);
  291. }
  292. // Tags
  293. foreach ( (array) get_the_tags($post->ID) as $tag ) {
  294. if ( empty($tag->slug ) )
  295. continue;
  296. $classes[] = 'tag-' . sanitize_html_class($tag->slug, $tag->term_id);
  297. }
  298. if ( !empty($class) ) {
  299. if ( !is_array( $class ) )
  300. $class = preg_split('#\s+#', $class);
  301. $classes = array_merge($classes, $class);
  302. }
  303. $classes = array_map('esc_attr', $classes);
  304. return apply_filters('post_class', $classes, $class, $post->ID);
  305. }
  306. /**
  307. * Display the classes for the body element.
  308. *
  309. * @since 2.8.0
  310. *
  311. * @param string|array $class One or more classes to add to the class list.
  312. */
  313. function body_class( $class = '' ) {
  314. // Separates classes with a single space, collates classes for body element
  315. echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
  316. }
  317. /**
  318. * Retrieve the classes for the body element as an array.
  319. *
  320. * @since 2.8.0
  321. *
  322. * @param string|array $class One or more classes to add to the class list.
  323. * @return array Array of classes.
  324. */
  325. function get_body_class( $class = '' ) {
  326. global $wp_query, $wpdb;
  327. $classes = array();
  328. if ( is_rtl() )
  329. $classes[] = 'rtl';
  330. if ( is_front_page() )
  331. $classes[] = 'home';
  332. if ( is_home() )
  333. $classes[] = 'blog';
  334. if ( is_archive() )
  335. $classes[] = 'archive';
  336. if ( is_date() )
  337. $classes[] = 'date';
  338. if ( is_search() )
  339. $classes[] = 'search';
  340. if ( is_paged() )
  341. $classes[] = 'paged';
  342. if ( is_attachment() )
  343. $classes[] = 'attachment';
  344. if ( is_404() )
  345. $classes[] = 'error404';
  346. if ( is_single() ) {
  347. $post_id = $wp_query->get_queried_object_id();
  348. $post = $wp_query->get_queried_object();
  349. $classes[] = 'single';
  350. $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id);
  351. $classes[] = 'postid-' . $post_id;
  352. if ( is_attachment() ) {
  353. $mime_type = get_post_mime_type($post_id);
  354. $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
  355. $classes[] = 'attachmentid-' . $post_id;
  356. $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
  357. }
  358. } elseif ( is_archive() ) {
  359. if ( is_author() ) {
  360. $author = $wp_query->get_queried_object();
  361. $classes[] = 'author';
  362. $classes[] = 'author-' . sanitize_html_class( $author->user_nicename , $author->ID );
  363. } elseif ( is_category() ) {
  364. $cat = $wp_query->get_queried_object();
  365. $classes[] = 'category';
  366. $classes[] = 'category-' . sanitize_html_class( $cat->slug, $cat->cat_ID );
  367. } elseif ( is_tag() ) {
  368. $tags = $wp_query->get_queried_object();
  369. $classes[] = 'tag';
  370. $classes[] = 'tag-' . sanitize_html_class( $tags->slug, $tags->term_id );
  371. }
  372. } elseif ( is_page() ) {
  373. $classes[] = 'page';
  374. $page_id = $wp_query->get_queried_object_id();
  375. $post = get_page($page_id);
  376. $classes[] = 'page-id-' . $page_id;
  377. if ( $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status = 'publish' LIMIT 1", $page_id) ) )
  378. $classes[] = 'page-parent';
  379. if ( $post->post_parent ) {
  380. $classes[] = 'page-child';
  381. $classes[] = 'parent-pageid-' . $post->post_parent;
  382. }
  383. if ( is_page_template() ) {
  384. $classes[] = 'page-template';
  385. $classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', get_post_meta( $page_id, '_wp_page_template', true ) ), '' );
  386. }
  387. } elseif ( is_search() ) {
  388. if ( !empty( $wp_query->posts ) )
  389. $classes[] = 'search-results';
  390. else
  391. $classes[] = 'search-no-results';
  392. }
  393. if ( is_user_logged_in() )
  394. $classes[] = 'logged-in';
  395. $page = $wp_query->get( 'page' );
  396. if ( !$page || $page < 2)
  397. $page = $wp_query->get( 'paged' );
  398. if ( $page && $page > 1 ) {
  399. $classes[] = 'paged-' . $page;
  400. if ( is_single() )
  401. $classes[] = 'single-paged-' . $page;
  402. elseif ( is_page() )
  403. $classes[] = 'page-paged-' . $page;
  404. elseif ( is_category() )
  405. $classes[] = 'category-paged-' . $page;
  406. elseif ( is_tag() )
  407. $classes[] = 'tag-paged-' . $page;
  408. elseif ( is_date() )
  409. $classes[] = 'date-paged-' . $page;
  410. elseif ( is_author() )
  411. $classes[] = 'author-paged-' . $page;
  412. elseif ( is_search() )
  413. $classes[] = 'search-paged-' . $page;
  414. }
  415. if ( !empty( $class ) ) {
  416. if ( !is_array( $class ) )
  417. $class = preg_split( '#\s+#', $class );
  418. $classes = array_merge( $classes, $class );
  419. }
  420. $classes = array_map( 'esc_attr', $classes );
  421. return apply_filters( 'body_class', $classes, $class );
  422. }
  423. /**
  424. * Whether post requires password and correct password has been provided.
  425. *
  426. * @since 2.7.0
  427. *
  428. * @param int|object $post An optional post. Global $post used if not provided.
  429. * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
  430. */
  431. function post_password_required( $post = null ) {
  432. $post = get_post($post);
  433. if ( empty($post->post_password) )
  434. return false;
  435. if ( !isset($_COOKIE['wp-postpass_' . COOKIEHASH]) )
  436. return true;
  437. if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password )
  438. return true;
  439. return false;
  440. }
  441. /**
  442. * Display "sticky" CSS class, if a post is sticky.
  443. *
  444. * @since 2.7.0
  445. *
  446. * @param int $post_id An optional post ID.
  447. */
  448. function sticky_class( $post_id = null ) {
  449. if ( !is_sticky($post_id) )
  450. return;
  451. echo " sticky";
  452. }
  453. /**
  454. * Page Template Functions for usage in Themes
  455. *
  456. * @package WordPress
  457. * @subpackage Template
  458. */
  459. /**
  460. * The formatted output of a list of pages.
  461. *
  462. * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
  463. * Quicktag one or more times). This tag must be within The Loop.
  464. *
  465. * The defaults for overwriting are:
  466. * 'next_or_number' - Default is 'number' (string). Indicates whether page
  467. * numbers should be used. Valid values are number and next.
  468. * 'nextpagelink' - Default is 'Next Page' (string). Text for link to next page.
  469. * of the bookmark.
  470. * 'previouspagelink' - Default is 'Previous Page' (string). Text for link to
  471. * previous page, if available.
  472. * 'pagelink' - Default is '%' (String).Format string for page numbers. The % in
  473. * the parameter string will be replaced with the page number, so Page %
  474. * generates "Page 1", "Page 2", etc. Defaults to %, just the page number.
  475. * 'before' - Default is '<p> Pages:' (string). The html or text to prepend to
  476. * each bookmarks.
  477. * 'after' - Default is '</p>' (string). The html or text to append to each
  478. * bookmarks.
  479. * 'link_before' - Default is '' (string). The html or text to prepend to each
  480. * Pages link inside the <a> tag. Also prepended to the current item, which
  481. * is not linked.
  482. * 'link_after' - Default is '' (string). The html or text to append to each
  483. * Pages link inside the <a> tag. Also appended to the current item, which
  484. * is not linked.
  485. *
  486. * @since 1.2.0
  487. * @access private
  488. *
  489. * @param string|array $args Optional. Overwrite the defaults.
  490. * @return string Formatted output in HTML.
  491. */
  492. function wp_link_pages($args = '') {
  493. $defaults = array(
  494. 'before' => '<p>' . __('Pages:'), 'after' => '</p>',
  495. 'link_before' => '', 'link_after' => '',
  496. 'next_or_number' => 'number', 'nextpagelink' => __('Next page'),
  497. 'previouspagelink' => __('Previous page'), 'pagelink' => '%',
  498. 'echo' => 1
  499. );
  500. $r = wp_parse_args( $args, $defaults );
  501. $r = apply_filters( 'wp_link_pages_args', $r );
  502. extract( $r, EXTR_SKIP );
  503. global $post, $page, $numpages, $multipage, $more, $pagenow;
  504. $output = '';
  505. if ( $multipage ) {
  506. if ( 'number' == $next_or_number ) {
  507. $output .= $before;
  508. for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) {
  509. $j = str_replace('%',$i,$pagelink);
  510. $output .= ' ';
  511. if ( ($i != $page) || ((!$more) && ($page==1)) ) {
  512. if ( 1 == $i ) {
  513. $output .= '<a href="' . get_permalink() . '">';
  514. } else {
  515. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  516. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  517. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  518. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  519. else
  520. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  521. }
  522. }
  523. $output .= $link_before;
  524. $output .= $j;
  525. $output .= $link_after;
  526. if ( ($i != $page) || ((!$more) && ($page==1)) )
  527. $output .= '</a>';
  528. }
  529. $output .= $after;
  530. } else {
  531. if ( $more ) {
  532. $output .= $before;
  533. $i = $page - 1;
  534. if ( $i && $more ) {
  535. if ( 1 == $i ) {
  536. $output .= '<a href="' . get_permalink() . '">';
  537. } else {
  538. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  539. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  540. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  541. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  542. else
  543. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  544. }
  545. $output .= $link_before. $previouspagelink . $link_after . '</a>';
  546. }
  547. $i = $page + 1;
  548. if ( $i <= $numpages && $more ) {
  549. if ( 1 == $i ) {
  550. $output .= '<a href="' . get_permalink() . '">';
  551. } else {
  552. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  553. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  554. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  555. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  556. else
  557. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  558. }
  559. $output .= $link_before. $nextpagelink . $link_after . '</a>';
  560. }
  561. $output .= $after;
  562. }
  563. }
  564. }
  565. if ( $echo )
  566. echo $output;
  567. return $output;
  568. }
  569. //
  570. // Post-meta: Custom per-post fields.
  571. //
  572. /**
  573. * Retrieve post custom meta data field.
  574. *
  575. * @since 1.5.0
  576. *
  577. * @param string $key Meta data key name.
  578. * @return bool|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
  579. */
  580. function post_custom( $key = '' ) {
  581. $custom = get_post_custom();
  582. if ( !isset( $custom[$key] ) )
  583. return false;
  584. elseif ( 1 == count($custom[$key]) )
  585. return $custom[$key][0];
  586. else
  587. return $custom[$key];
  588. }
  589. /**
  590. * Display list of post custom fields.
  591. *
  592. * @internal This will probably change at some point...
  593. * @since 1.2.0
  594. * @uses apply_filters() Calls 'the_meta_key' on list item HTML content, with key and value as separate parameters.
  595. */
  596. function the_meta() {
  597. if ( $keys = get_post_custom_keys() ) {
  598. echo "<ul class='post-meta'>\n";
  599. foreach ( (array) $keys as $key ) {
  600. $keyt = trim($key);
  601. if ( '_' == $keyt{0} )
  602. continue;
  603. $values = array_map('trim', get_post_custom_values($key));
  604. $value = implode($values,', ');
  605. echo apply_filters('the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value);
  606. }
  607. echo "</ul>\n";
  608. }
  609. }
  610. //
  611. // Pages
  612. //
  613. /**
  614. * Retrieve or display list of pages as a dropdown (select list).
  615. *
  616. * @since 2.1.0
  617. *
  618. * @param array|string $args Optional. Override default arguments.
  619. * @return string HTML content, if not displaying.
  620. */
  621. function wp_dropdown_pages($args = '') {
  622. $defaults = array(
  623. 'depth' => 0, 'child_of' => 0,
  624. 'selected' => 0, 'echo' => 1,
  625. 'name' => 'page_id', 'id' => '',
  626. 'show_option_none' => '', 'show_option_no_change' => '',
  627. 'option_none_value' => ''
  628. );
  629. $r = wp_parse_args( $args, $defaults );
  630. extract( $r, EXTR_SKIP );
  631. $pages = get_pages($r);
  632. $output = '';
  633. $name = esc_attr($name);
  634. // Back-compat with old system where both id and name were based on $name argument
  635. if ( empty($id) )
  636. $id = $name;
  637. if ( ! empty($pages) ) {
  638. $output = "<select name=\"$name\" id=\"$id\">\n";
  639. if ( $show_option_no_change )
  640. $output .= "\t<option value=\"-1\">$show_option_no_change</option>";
  641. if ( $show_option_none )
  642. $output .= "\t<option value=\"" . esc_attr($option_none_value) . "\">$show_option_none</option>\n";
  643. $output .= walk_page_dropdown_tree($pages, $depth, $r);
  644. $output .= "</select>\n";
  645. }
  646. $output = apply_filters('wp_dropdown_pages', $output);
  647. if ( $echo )
  648. echo $output;
  649. return $output;
  650. }
  651. /**
  652. * Retrieve or display list of pages in list (li) format.
  653. *
  654. * @since 1.5.0
  655. *
  656. * @param array|string $args Optional. Override default arguments.
  657. * @return string HTML content, if not displaying.
  658. */
  659. function wp_list_pages($args = '') {
  660. $defaults = array(
  661. 'depth' => 0, 'show_date' => '',
  662. 'date_format' => get_option('date_format'),
  663. 'child_of' => 0, 'exclude' => '',
  664. 'title_li' => __('Pages'), 'echo' => 1,
  665. 'authors' => '', 'sort_column' => 'menu_order, post_title',
  666. 'link_before' => '', 'link_after' => '', 'walker' => '',
  667. );
  668. $r = wp_parse_args( $args, $defaults );
  669. extract( $r, EXTR_SKIP );
  670. $output = '';
  671. $current_page = 0;
  672. // sanitize, mostly to keep spaces out
  673. $r['exclude'] = preg_replace('/[^0-9,]/', '', $r['exclude']);
  674. // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
  675. $exclude_array = ( $r['exclude'] ) ? explode(',', $r['exclude']) : array();
  676. $r['exclude'] = implode( ',', apply_filters('wp_list_pages_excludes', $exclude_array) );
  677. // Query pages.
  678. $r['hierarchical'] = 0;
  679. $pages = get_pages($r);
  680. if ( !empty($pages) ) {
  681. if ( $r['title_li'] )
  682. $output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
  683. global $wp_query;
  684. if ( is_page() || is_attachment() || $wp_query->is_posts_page )
  685. $current_page = $wp_query->get_queried_object_id();
  686. $output .= walk_page_tree($pages, $r['depth'], $current_page, $r);
  687. if ( $r['title_li'] )
  688. $output .= '</ul></li>';
  689. }
  690. $output = apply_filters('wp_list_pages', $output, $r);
  691. if ( $r['echo'] )
  692. echo $output;
  693. else
  694. return $output;
  695. }
  696. /**
  697. * Display or retrieve list of pages with optional home link.
  698. *
  699. * The arguments are listed below and part of the arguments are for {@link
  700. * wp_list_pages()} function. Check that function for more info on those
  701. * arguments.
  702. *
  703. * <ul>
  704. * <li><strong>sort_column</strong> - How to sort the list of pages. Defaults
  705. * to page title. Use column for posts table.</li>
  706. * <li><strong>menu_class</strong> - Class to use for the div ID which contains
  707. * the page list. Defaults to 'menu'.</li>
  708. * <li><strong>echo</strong> - Whether to echo list or return it. Defaults to
  709. * echo.</li>
  710. * <li><strong>link_before</strong> - Text before show_home argument text.</li>
  711. * <li><strong>link_after</strong> - Text after show_home argument text.</li>
  712. * <li><strong>show_home</strong> - If you set this argument, then it will
  713. * display the link to the home page. The show_home argument really just needs
  714. * to be set to the value of the text of the link.</li>
  715. * </ul>
  716. *
  717. * @since 2.7.0
  718. *
  719. * @param array|string $args
  720. */
  721. function wp_page_menu( $args = array() ) {
  722. $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
  723. $args = wp_parse_args( $args, $defaults );
  724. $args = apply_filters( 'wp_page_menu_args', $args );
  725. $menu = '';
  726. $list_args = $args;
  727. // Show Home in the menu
  728. if ( ! empty($args['show_home']) ) {
  729. if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
  730. $text = __('Home');
  731. else
  732. $text = $args['show_home'];
  733. $class = '';
  734. if ( is_front_page() && !is_paged() )
  735. $class = 'class="current_page_item"';
  736. $menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '" title="' . esc_attr($text) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
  737. // If the front page is a page, add it to the exclude list
  738. if (get_option('show_on_front') == 'page') {
  739. if ( !empty( $list_args['exclude'] ) ) {
  740. $list_args['exclude'] .= ',';
  741. } else {
  742. $list_args['exclude'] = '';
  743. }
  744. $list_args['exclude'] .= get_option('page_on_front');
  745. }
  746. }
  747. $list_args['echo'] = false;
  748. $list_args['title_li'] = '';
  749. $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
  750. if ( $menu )
  751. $menu = '<ul>' . $menu . '</ul>';
  752. $menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
  753. $menu = apply_filters( 'wp_page_menu', $menu, $args );
  754. if ( $args['echo'] )
  755. echo $menu;
  756. else
  757. return $menu;
  758. }
  759. //
  760. // Page helpers
  761. //
  762. /**
  763. * Retrieve HTML list content for page list.
  764. *
  765. * @uses Walker_Page to create HTML list content.
  766. * @since 2.1.0
  767. * @see Walker_Page::walk() for parameters and return description.
  768. */
  769. function walk_page_tree($pages, $depth, $current_page, $r) {
  770. if ( empty($r['walker']) )
  771. $walker = new Walker_Page;
  772. else
  773. $walker = $r['walker'];
  774. $args = array($pages, $depth, $r, $current_page);
  775. return call_user_func_array(array(&$walker, 'walk'), $args);
  776. }
  777. /**
  778. * Retrieve HTML dropdown (select) content for page list.
  779. *
  780. * @uses Walker_PageDropdown to create HTML dropdown content.
  781. * @since 2.1.0
  782. * @see Walker_PageDropdown::walk() for parameters and return description.
  783. */
  784. function walk_page_dropdown_tree() {
  785. $args = func_get_args();
  786. if ( empty($args[2]['walker']) ) // the user's options are the third parameter
  787. $walker = new Walker_PageDropdown;
  788. else
  789. $walker = $args[2]['walker'];
  790. return call_user_func_array(array(&$walker, 'walk'), $args);
  791. }
  792. //
  793. // Attachments
  794. //
  795. /**
  796. * Display an attachment page link using an image or icon.
  797. *
  798. * @since 2.0.0
  799. *
  800. * @param int $id Optional. Post ID.
  801. * @param bool $fullsize Optional, default is false. Whether to use full size.
  802. * @param bool $deprecated Deprecated. Not used.
  803. * @param bool $permalink Optional, default is false. Whether to include permalink.
  804. */
  805. function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
  806. if ( !empty( $deprecated ) )
  807. _deprecated_argument( __FUNCTION__, '2.5' );
  808. if ( $fullsize )
  809. echo wp_get_attachment_link($id, 'full', $permalink);
  810. else
  811. echo wp_get_attachment_link($id, 'thumbnail', $permalink);
  812. }
  813. /**
  814. * Retrieve an attachment page link using an image or icon, if possible.
  815. *
  816. * @since 2.5.0
  817. * @uses apply_filters() Calls 'wp_get_attachment_link' filter on HTML content with same parameters as function.
  818. *
  819. * @param int $id Optional. Post ID.
  820. * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string.
  821. * @param bool $permalink Optional, default is false. Whether to add permalink to image.
  822. * @param bool $icon Optional, default is false. Whether to include icon.
  823. * @param string $text Optional, default is false. If string, then will be link text.
  824. * @return string HTML content.
  825. */
  826. function wp_get_attachment_link($id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false) {
  827. $id = intval($id);
  828. $_post = & get_post( $id );
  829. if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
  830. return __('Missing Attachment');
  831. if ( $permalink )
  832. $url = get_attachment_link($_post->ID);
  833. $post_title = esc_attr($_post->post_title);
  834. if ( $text ) {
  835. $link_text = esc_attr($text);
  836. } elseif ( ( is_int($size) && $size != 0 ) or ( is_string($size) && $size != 'none' ) or $size != false ) {
  837. $link_text = wp_get_attachment_image($id, $size, $icon);
  838. } else {
  839. $link_text = '';
  840. }
  841. if( trim($link_text) == '' )
  842. $link_text = $_post->post_title;
  843. return apply_filters( 'wp_get_attachment_link', "<a href='$url' title='$post_title'>$link_text</a>", $id, $size, $permalink, $icon, $text );
  844. }
  845. /**
  846. * Wrap attachment in <<p>> element before content.
  847. *
  848. * @since 2.0.0
  849. * @uses apply_filters() Calls 'prepend_attachment' hook on HTML content.
  850. *
  851. * @param string $content
  852. * @return string
  853. */
  854. function prepend_attachment($content) {
  855. global $post;
  856. if ( empty($post->post_type) || $post->post_type != 'attachment' )
  857. return $content;
  858. $p = '<p class="attachment">';
  859. // show the medium sized image representation of the attachment if available, and link to the raw file
  860. $p .= wp_get_attachment_link(0, 'medium', false);
  861. $p .= '</p>';
  862. $p = apply_filters('prepend_attachment', $p);
  863. return "$p\n$content";
  864. }
  865. //
  866. // Misc
  867. //
  868. /**
  869. * Retrieve protected post password form content.
  870. *
  871. * @since 1.0.0
  872. * @uses apply_filters() Calls 'the_password_form' filter on output.
  873. *
  874. * @return string HTML content for password form for password protected post.
  875. */
  876. function get_the_password_form() {
  877. global $post;
  878. $label = 'pwbox-'.(empty($post->ID) ? rand() : $post->ID);
  879. $output = '<form action="' . get_option('siteurl') . '/wp-pass.php" method="post">
  880. <p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
  881. <p><label for="' . $label . '">' . __("Password:") . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr__("Submit") . '" /></p>
  882. </form>
  883. ';
  884. return apply_filters('the_password_form', $output);
  885. }
  886. /**
  887. * Whether currently in a page template.
  888. *
  889. * This template tag allows you to determine if you are in a page template.
  890. * You can optionally provide a template name and then the check will be
  891. * specific to that template.
  892. *
  893. * @since 2.5.0
  894. * @uses $wp_query
  895. *
  896. * @param string $template The specific template name if specific matching is required.
  897. * @return bool False on failure, true if success.
  898. */
  899. function is_page_template($template = '') {
  900. if (!is_page()) {
  901. return false;
  902. }
  903. global $wp_query;
  904. $page = $wp_query->get_queried_object();
  905. $custom_fields = get_post_custom_values('_wp_page_template',$page->ID);
  906. $page_template = $custom_fields[0];
  907. // We have no argument passed so just see if a page_template has been specified
  908. if ( empty( $template ) ) {
  909. if (!empty( $page_template ) ) {
  910. return true;
  911. }
  912. } elseif ( $template == $page_template) {
  913. return true;
  914. }
  915. return false;
  916. }
  917. /**
  918. * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  919. *
  920. * @package WordPress
  921. * @subpackage Post_Revisions
  922. * @since 2.6.0
  923. *
  924. * @uses date_i18n()
  925. *
  926. * @param int|object $revision Revision ID or revision object.
  927. * @param bool $link Optional, default is true. Link to revisions's page?
  928. * @return string i18n formatted datetimestamp or localized 'Current Revision'.
  929. */
  930. function wp_post_revision_title( $revision, $link = true ) {
  931. if ( !$revision = get_post( $revision ) )
  932. return $revision;
  933. if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  934. return false;
  935. /* translators: revision date format, see http://php.net/date */
  936. $datef = _x( 'j F, Y @ G:i', 'revision date format');
  937. /* translators: 1: date */
  938. $autosavef = __( '%1$s [Autosave]' );
  939. /* translators: 1: date */
  940. $currentf = __( '%1$s [Current Revision]' );
  941. $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  942. if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  943. $date = "<a href='$link'>$date</a>";
  944. if ( !wp_is_post_revision( $revision ) )
  945. $date = sprintf( $currentf, $date );
  946. elseif ( wp_is_post_autosave( $revision ) )
  947. $date = sprintf( $autosavef, $date );
  948. return $date;
  949. }
  950. /**
  951. * Display list of a post's revisions.
  952. *
  953. * Can output either a UL with edit links or a TABLE with diff interface, and
  954. * restore action links.
  955. *
  956. * Second argument controls parameters:
  957. * (bool) parent : include the parent (the "Current Revision") in the list.
  958. * (string) format : 'list' or 'form-table'. 'list' outputs UL, 'form-table'
  959. * outputs TABLE with UI.
  960. * (int) right : what revision is currently being viewed - used in
  961. * form-table format.
  962. * (int) left : what revision is currently being diffed against right -
  963. * used in form-table format.
  964. *
  965. * @package WordPress
  966. * @subpackage Post_Revisions
  967. * @since 2.6.0
  968. *
  969. * @uses wp_get_post_revisions()
  970. * @uses wp_post_revision_title()
  971. * @uses get_edit_post_link()
  972. * @uses get_the_author_meta()
  973. *
  974. * @todo split into two functions (list, form-table) ?
  975. *
  976. * @param int|object $post_id Post ID or post object.
  977. * @param string|array $args See description {@link wp_parse_args()}.
  978. * @return null
  979. */
  980. function wp_list_post_revisions( $post_id = 0, $args = null ) {
  981. if ( !$post = get_post( $post_id ) )
  982. return;
  983. $defaults = array( 'parent' => false, 'right' => false, 'left' => false, 'format' => 'list', 'type' => 'all' );
  984. extract( wp_parse_args( $args, $defaults ), EXTR_SKIP );
  985. switch ( $type ) {
  986. case 'autosave' :
  987. if ( !$autosave = wp_get_post_autosave( $post->ID ) )
  988. return;
  989. $revisions = array( $autosave );
  990. break;
  991. case 'revision' : // just revisions - remove autosave later
  992. case 'all' :
  993. default :
  994. if ( !$revisions = wp_get_post_revisions( $post->ID ) )
  995. return;
  996. break;
  997. }
  998. /* translators: post revision: 1: when, 2: author name */
  999. $titlef = _x( '%1$s by %2$s', 'post revision' );
  1000. if ( $parent )
  1001. array_unshift( $revisions, $post );
  1002. $rows = '';
  1003. $class = false;
  1004. $can_edit_post = current_user_can( 'edit_post', $post->ID );
  1005. foreach ( $revisions as $revision ) {
  1006. if ( !current_user_can( 'read_post', $revision->ID ) )
  1007. continue;
  1008. if ( 'revision' === $type && wp_is_post_autosave( $revision ) )
  1009. continue;
  1010. $date = wp_post_revision_title( $revision );
  1011. $name = get_the_author_meta( 'display_name', $revision->post_author );
  1012. if ( 'form-table' == $format ) {
  1013. if ( $left )
  1014. $left_checked = $left == $revision->ID ? ' checked="checked"' : '';
  1015. else
  1016. $left_checked = $right_checked ? ' checked="checked"' : ''; // [sic] (the next one)
  1017. $right_checked = $right == $revision->ID ? ' checked="checked"' : '';
  1018. $class = $class ? '' : " class='alternate'";
  1019. if ( $post->ID != $revision->ID && $can_edit_post )
  1020. $actions = '<a href="' . wp_nonce_url( add_query_arg( array( 'revision' => $revision->ID, 'action' => 'restore' ) ), "restore-post_$post->ID|$revision->ID" ) . '">' . __( 'Restore' ) . '</a>';
  1021. else
  1022. $actions = '';
  1023. $rows .= "<tr$class>\n";
  1024. $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='left' value='$revision->ID'$left_checked /></th>\n";
  1025. $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='right' value='$revision->ID'$right_checked /></th>\n";
  1026. $rows .= "\t<td>$date</td>\n";
  1027. $rows .= "\t<td>$name</td>\n";
  1028. $rows .= "\t<td class='action-links'>$actions</td>\n";
  1029. $rows .= "</tr>\n";
  1030. } else {
  1031. $title = sprintf( $titlef, $date, $name );
  1032. $rows .= "\t<li>$title</li>\n";
  1033. }
  1034. }
  1035. if ( 'form-table' == $format ) : ?>
  1036. <form action="revision.php" method="get">
  1037. <div class="tablenav">
  1038. <div class="alignleft">
  1039. <input type="submit" class="button-secondary" value="<?php esc_attr_e( 'Compare Revisions' ); ?>" />
  1040. <input type="hidden" name="action" value="diff" />
  1041. <input type="hidden" name="post_type" value="<?php echo esc_attr($post->post_type); ?>" />
  1042. </div>
  1043. </div>
  1044. <br class="clear" />
  1045. <table class="widefat post-revisions" cellspacing="0" id="post-revisions">
  1046. <col />
  1047. <col />
  1048. <col style="width: 33%" />
  1049. <col style="width: 33%" />
  1050. <col style="width: 33%" />
  1051. <thead>
  1052. <tr>
  1053. <th scope="col"><?php /* translators: column name in revisons */ _ex( 'Old', 'revisions column name' ); ?></th>
  1054. <th scope="col"><?php /* translators: column name in revisons */ _ex( 'New', 'revisions column name' ); ?></th>
  1055. <th scope="col"><?php /* translators: column name in revisons */ _ex( 'Date Created', 'revisions column name' ); ?></th>
  1056. <th scope="col"><?php _e( 'Author' ); ?></th>
  1057. <th scope="col" class="action-links"><?php _e( 'Actions' ); ?></th>
  1058. </tr>
  1059. </thead>
  1060. <tbody>
  1061. <?php echo $rows; ?>
  1062. </tbody>
  1063. </table>
  1064. </form>
  1065. <?php
  1066. else :
  1067. echo "<ul class='post-revisions'>\n";
  1068. echo $rows;
  1069. echo "</ul>";
  1070. endif;
  1071. }