wp/wp-includes/link-template.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     5  * @package WordPress
     5  * @package WordPress
     6  * @subpackage Template
     6  * @subpackage Template
     7  */
     7  */
     8 
     8 
     9 /**
     9 /**
    10  * Display the permalink for the current post.
    10  * Displays the permalink for the current post.
    11  *
    11  *
    12  * @since 1.2.0
    12  * @since 1.2.0
    13  */
    13  * @since 4.4.0 Added the `$post` parameter.
    14 function the_permalink() {
    14  *
    15 	/**
    15  * @param int|WP_Post $post Optional. Post ID or post object. Default is the global `$post`.
    16 	 * Filter the display of the permalink for the current post.
    16  */
       
    17 function the_permalink( $post = 0 ) {
       
    18 	/**
       
    19 	 * Filters the display of the permalink for the current post.
    17 	 *
    20 	 *
    18 	 * @since 1.5.0
    21 	 * @since 1.5.0
    19 	 *
    22 	 * @since 4.4.0 Added the `$post` parameter.
    20 	 * @param string $permalink The permalink for the current post.
    23 	 *
    21 	 */
    24 	 * @param string      $permalink The permalink for the current post.
    22 	echo esc_url( apply_filters( 'the_permalink', get_permalink() ) );
    25 	 * @param int|WP_Post $post      Post ID, WP_Post object, or 0. Default 0.
    23 }
    26 	 */
    24 
    27 	echo esc_url( apply_filters( 'the_permalink', get_permalink( $post ), $post ) );
    25 /**
    28 }
    26  * Retrieve trailing slash string, if blog set for adding trailing slashes.
    29 
       
    30 /**
       
    31  * Retrieves a trailing-slashed string if the site is set for adding trailing slashes.
    27  *
    32  *
    28  * Conditionally adds a trailing slash if the permalink structure has a trailing
    33  * Conditionally adds a trailing slash if the permalink structure has a trailing
    29  * slash, strips the trailing slash if not. The string is passed through the
    34  * slash, strips the trailing slash if not. The string is passed through the
    30  * 'user_trailingslashit' filter. Will remove trailing slash from string, if
    35  * {@see 'user_trailingslashit'} filter. Will remove trailing slash from string, if
    31  * blog is not set to have them.
    36  * site is not set to have them.
    32  *
    37  *
    33  * @since 2.2.0
    38  * @since 2.2.0
    34  * @uses $wp_rewrite
    39  *
    35  *
    40  * @global WP_Rewrite $wp_rewrite
    36  * @param string $string URL with or without a trailing slash.
    41  *
    37  * @param string $type_of_url The type of URL being considered (e.g. single, category, etc) for use in the filter.
    42  * @param string $string      URL with or without a trailing slash.
       
    43  * @param string $type_of_url Optional. The type of URL being considered (e.g. single, category, etc)
       
    44  *                            for use in the filter. Default empty string.
    38  * @return string The URL with the trailing slash appended or stripped.
    45  * @return string The URL with the trailing slash appended or stripped.
    39  */
    46  */
    40 function user_trailingslashit($string, $type_of_url = '') {
    47 function user_trailingslashit($string, $type_of_url = '') {
    41 	global $wp_rewrite;
    48 	global $wp_rewrite;
    42 	if ( $wp_rewrite->use_trailing_slashes )
    49 	if ( $wp_rewrite->use_trailing_slashes )
    43 		$string = trailingslashit($string);
    50 		$string = trailingslashit($string);
    44 	else
    51 	else
    45 		$string = untrailingslashit($string);
    52 		$string = untrailingslashit($string);
    46 
    53 
    47 	/**
    54 	/**
    48 	 * Filter the trailing slashed string, depending on whether the site is set
    55 	 * Filters the trailing-slashed string, depending on whether the site is set to use trailing slashes.
    49 	 * to use training slashes.
       
    50 	 *
    56 	 *
    51 	 * @since 2.2.0
    57 	 * @since 2.2.0
    52 	 *
    58 	 *
    53 	 * @param string $string      URL with or without a trailing slash.
    59 	 * @param string $string      URL with or without a trailing slash.
    54 	 * @param string $type_of_url The type of URL being considered. Accepts 'single', 'single_trackback',
    60 	 * @param string $type_of_url The type of URL being considered. Accepts 'single', 'single_trackback',
    55 	 *                            'single_feed', 'single_paged', 'feed', 'category', 'page', 'year',
    61 	 *                            'single_feed', 'single_paged', 'commentpaged', 'paged', 'home', 'feed',
    56 	 *                            'month', 'day', 'paged', 'post_type_archive'.
    62 	 *                            'category', 'page', 'year', 'month', 'day', 'post_type_archive'.
    57 	 */
    63 	 */
    58 	$string = apply_filters( 'user_trailingslashit', $string, $type_of_url );
    64 	return apply_filters( 'user_trailingslashit', $string, $type_of_url );
    59 	return $string;
    65 }
    60 }
    66 
    61 
    67 /**
    62 /**
    68  * Displays the permalink anchor for the current post.
    63  * Display permalink anchor for current post.
       
    64  *
    69  *
    65  * The permalink mode title will use the post title for the 'a' element 'id'
    70  * The permalink mode title will use the post title for the 'a' element 'id'
    66  * attribute. The id mode uses 'post-' with the post ID for the 'id' attribute.
    71  * attribute. The id mode uses 'post-' with the post ID for the 'id' attribute.
    67  *
    72  *
    68  * @since 0.71
    73  * @since 0.71
    69  *
    74  *
    70  * @param string $mode Permalink mode can be either 'title', 'id', or default, which is 'id'.
    75  * @param string $mode Optional. Permalink mode. Accepts 'title' or 'id'. Default 'id'.
    71  */
    76  */
    72 function permalink_anchor( $mode = 'id' ) {
    77 function permalink_anchor( $mode = 'id' ) {
    73 	$post = get_post();
    78 	$post = get_post();
    74 	switch ( strtolower( $mode ) ) {
    79 	switch ( strtolower( $mode ) ) {
    75 		case 'title':
    80 		case 'title':
    82 			break;
    87 			break;
    83 	}
    88 	}
    84 }
    89 }
    85 
    90 
    86 /**
    91 /**
    87  * Retrieve full permalink for current post or post ID.
    92  * Retrieves the full permalink for the current post or post ID.
    88  *
    93  *
    89  * This function is an alias for get_permalink().
    94  * This function is an alias for get_permalink().
    90  *
    95  *
    91  * @since 3.9.0
    96  * @since 3.9.0
    92  *
    97  *
    93  * @see get_permalink()
    98  * @see get_permalink()
    94  *
    99  *
    95  * @param int|WP_Post $id        Optional. Post ID or post object. Default is the current post.
   100  * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
    96  * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
   101  * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
    97  * @return string|bool The permalink URL or false if post does not exist.
   102  *
    98  */
   103  * @return string|false The permalink URL or false if post does not exist.
    99 function get_the_permalink( $id = 0, $leavename = false ) {
   104  */
   100 	return get_permalink( $id, $leavename );
   105 function get_the_permalink( $post = 0, $leavename = false ) {
   101 }
   106 	return get_permalink( $post, $leavename );
   102 
   107 }
   103 /**
   108 
   104  * Retrieve full permalink for current post or post ID.
   109 /**
       
   110  * Retrieves the full permalink for the current post or post ID.
   105  *
   111  *
   106  * @since 1.0.0
   112  * @since 1.0.0
   107  *
   113  *
   108  * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
   114  * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
   109  * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
   115  * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
   110  * @return string|bool The permalink URL or false if post does not exist.
   116  * @return string|false The permalink URL or false if post does not exist.
   111  */
   117  */
   112 function get_permalink( $id = 0, $leavename = false ) {
   118 function get_permalink( $post = 0, $leavename = false ) {
   113 	$rewritecode = array(
   119 	$rewritecode = array(
   114 		'%year%',
   120 		'%year%',
   115 		'%monthnum%',
   121 		'%monthnum%',
   116 		'%day%',
   122 		'%day%',
   117 		'%hour%',
   123 		'%hour%',
   122 		'%category%',
   128 		'%category%',
   123 		'%author%',
   129 		'%author%',
   124 		$leavename? '' : '%pagename%',
   130 		$leavename? '' : '%pagename%',
   125 	);
   131 	);
   126 
   132 
   127 	if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter ) {
   133 	if ( is_object( $post ) && isset( $post->filter ) && 'sample' == $post->filter ) {
   128 		$post = $id;
       
   129 		$sample = true;
   134 		$sample = true;
   130 	} else {
   135 	} else {
   131 		$post = get_post($id);
   136 		$post = get_post( $post );
   132 		$sample = false;
   137 		$sample = false;
   133 	}
   138 	}
   134 
   139 
   135 	if ( empty($post->ID) )
   140 	if ( empty($post->ID) )
   136 		return false;
   141 		return false;
   143 		return get_post_permalink($post, $leavename, $sample);
   148 		return get_post_permalink($post, $leavename, $sample);
   144 
   149 
   145 	$permalink = get_option('permalink_structure');
   150 	$permalink = get_option('permalink_structure');
   146 
   151 
   147 	/**
   152 	/**
   148 	 * Filter the permalink structure for a post before token replacement occurs.
   153 	 * Filters the permalink structure for a post before token replacement occurs.
   149 	 *
   154 	 *
   150 	 * Only applies to posts with post_type of 'post'.
   155 	 * Only applies to posts with post_type of 'post'.
   151 	 *
   156 	 *
   152 	 * @since 3.0.0
   157 	 * @since 3.0.0
   153 	 *
   158 	 *
   162 
   167 
   163 		$category = '';
   168 		$category = '';
   164 		if ( strpos($permalink, '%category%') !== false ) {
   169 		if ( strpos($permalink, '%category%') !== false ) {
   165 			$cats = get_the_category($post->ID);
   170 			$cats = get_the_category($post->ID);
   166 			if ( $cats ) {
   171 			if ( $cats ) {
   167 				usort($cats, '_usort_terms_by_ID'); // order by ID
   172 				$cats = wp_list_sort( $cats, array(
       
   173 					'term_id' => 'ASC',
       
   174 				) );
   168 
   175 
   169 				/**
   176 				/**
   170 				 * Filter the category that gets used in the %category% permalink token.
   177 				 * Filters the category that gets used in the %category% permalink token.
   171 				 *
   178 				 *
   172 				 * @since 3.5.0
   179 				 * @since 3.5.0
   173 				 *
   180 				 *
   174 				 * @param stdClass $cat  The category to use in the permalink.
   181 				 * @param WP_Term  $cat  The category to use in the permalink.
   175 				 * @param array    $cats Array of all categories associated with the post.
   182 				 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
   176 				 * @param WP_Post  $post The post in question.
   183 				 * @param WP_Post  $post The post in question.
   177 				 */
   184 				 */
   178 				$category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
   185 				$category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
   179 
   186 
   180 				$category_object = get_term( $category_object, 'category' );
   187 				$category_object = get_term( $category_object, 'category' );
   184 			}
   191 			}
   185 			// show default category in permalinks, without
   192 			// show default category in permalinks, without
   186 			// having to assign it explicitly
   193 			// having to assign it explicitly
   187 			if ( empty($category) ) {
   194 			if ( empty($category) ) {
   188 				$default_category = get_term( get_option( 'default_category' ), 'category' );
   195 				$default_category = get_term( get_option( 'default_category' ), 'category' );
   189 				$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
   196 				if ( $default_category && ! is_wp_error( $default_category ) ) {
       
   197 					$category = $default_category->slug;
       
   198 				}
   190 			}
   199 			}
   191 		}
   200 		}
   192 
   201 
   193 		$author = '';
   202 		$author = '';
   194 		if ( strpos($permalink, '%author%') !== false ) {
   203 		if ( strpos($permalink, '%author%') !== false ) {
   216 	} else { // if they're not using the fancy permalink option
   225 	} else { // if they're not using the fancy permalink option
   217 		$permalink = home_url('?p=' . $post->ID);
   226 		$permalink = home_url('?p=' . $post->ID);
   218 	}
   227 	}
   219 
   228 
   220 	/**
   229 	/**
   221 	 * Filter the permalink for a post.
   230 	 * Filters the permalink for a post.
   222 	 *
   231 	 *
   223 	 * Only applies to posts with post_type of 'post'.
   232 	 * Only applies to posts with post_type of 'post'.
   224 	 *
   233 	 *
   225 	 * @since 1.5.0
   234 	 * @since 1.5.0
   226 	 *
   235 	 *
   230 	 */
   239 	 */
   231 	return apply_filters( 'post_link', $permalink, $post, $leavename );
   240 	return apply_filters( 'post_link', $permalink, $post, $leavename );
   232 }
   241 }
   233 
   242 
   234 /**
   243 /**
   235  * Retrieve the permalink for a post with a custom post type.
   244  * Retrieves the permalink for a post of a custom post type.
   236  *
   245  *
   237  * @since 3.0.0
   246  * @since 3.0.0
   238  *
   247  *
   239  * @param int $id Optional. Post ID.
   248  * @global WP_Rewrite $wp_rewrite
   240  * @param bool $leavename Optional, defaults to false. Whether to keep post name.
   249  *
   241  * @param bool $sample Optional, defaults to false. Is it a sample permalink.
   250  * @param int|WP_Post $id        Optional. Post ID or post object. Default is the global `$post`.
   242  * @return string The post permalink.
   251  * @param bool        $leavename Optional, defaults to false. Whether to keep post name. Default false.
       
   252  * @param bool        $sample    Optional, defaults to false. Is it a sample permalink. Default false.
       
   253  * @return string|WP_Error The post permalink.
   243  */
   254  */
   244 function get_post_permalink( $id = 0, $leavename = false, $sample = false ) {
   255 function get_post_permalink( $id = 0, $leavename = false, $sample = false ) {
   245 	global $wp_rewrite;
   256 	global $wp_rewrite;
   246 
   257 
   247 	$post = get_post($id);
   258 	$post = get_post($id);
   251 
   262 
   252 	$post_link = $wp_rewrite->get_extra_permastruct($post->post_type);
   263 	$post_link = $wp_rewrite->get_extra_permastruct($post->post_type);
   253 
   264 
   254 	$slug = $post->post_name;
   265 	$slug = $post->post_name;
   255 
   266 
   256 	$draft_or_pending = isset( $post->post_status ) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft', 'future' ) );
   267 	$draft_or_pending = get_post_status( $post ) && in_array( get_post_status( $post ), array( 'draft', 'pending', 'auto-draft', 'future' ) );
   257 
   268 
   258 	$post_type = get_post_type_object($post->post_type);
   269 	$post_type = get_post_type_object($post->post_type);
   259 
   270 
   260 	if ( $post_type->hierarchical ) {
   271 	if ( $post_type->hierarchical ) {
   261 		$slug = get_page_uri( $id );
   272 		$slug = get_page_uri( $post );
   262 	}
   273 	}
   263 
   274 
   264 	if ( !empty($post_link) && ( !$draft_or_pending || $sample ) ) {
   275 	if ( !empty($post_link) && ( !$draft_or_pending || $sample ) ) {
   265 		if ( ! $leavename ) {
   276 		if ( ! $leavename ) {
   266 			$post_link = str_replace("%$post->post_type%", $slug, $post_link);
   277 			$post_link = str_replace("%$post->post_type%", $slug, $post_link);
   273 			$post_link = add_query_arg(array('post_type' => $post->post_type, 'p' => $post->ID), '');
   284 			$post_link = add_query_arg(array('post_type' => $post->post_type, 'p' => $post->ID), '');
   274 		$post_link = home_url($post_link);
   285 		$post_link = home_url($post_link);
   275 	}
   286 	}
   276 
   287 
   277 	/**
   288 	/**
   278 	 * Filter the permalink for a post with a custom post type.
   289 	 * Filters the permalink for a post of a custom post type.
   279 	 *
   290 	 *
   280 	 * @since 3.0.0
   291 	 * @since 3.0.0
   281 	 *
   292 	 *
   282 	 * @param string  $post_link The post's permalink.
   293 	 * @param string  $post_link The post's permalink.
   283 	 * @param WP_Post $post      The post in question.
   294 	 * @param WP_Post $post      The post in question.
   286 	 */
   297 	 */
   287 	return apply_filters( 'post_type_link', $post_link, $post, $leavename, $sample );
   298 	return apply_filters( 'post_type_link', $post_link, $post, $leavename, $sample );
   288 }
   299 }
   289 
   300 
   290 /**
   301 /**
   291  * Retrieve permalink from post ID.
   302  * Retrieves the permalink for the current page or page ID.
   292  *
       
   293  * @since 1.0.0
       
   294  *
       
   295  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
       
   296  * @param mixed $deprecated Not used.
       
   297  * @return string
       
   298  */
       
   299 function post_permalink( $post_id = 0, $deprecated = '' ) {
       
   300 	if ( !empty( $deprecated ) )
       
   301 		_deprecated_argument( __FUNCTION__, '1.3' );
       
   302 
       
   303 	return get_permalink($post_id);
       
   304 }
       
   305 
       
   306 /**
       
   307  * Retrieve the permalink for current page or page ID.
       
   308  *
   303  *
   309  * Respects page_on_front. Use this one.
   304  * Respects page_on_front. Use this one.
   310  *
   305  *
   311  * @since 1.5.0
   306  * @since 1.5.0
   312  *
   307  *
   313  * @param int|object $post Optional. Post ID or object.
   308  * @param int|WP_Post $post      Optional. Post ID or object. Default uses the global `$post`.
   314  * @param bool $leavename Optional, defaults to false. Whether to keep page name.
   309  * @param bool        $leavename Optional. Whether to keep the page name. Default false.
   315  * @param bool $sample Optional, defaults to false. Is it a sample permalink.
   310  * @param bool        $sample    Optional. Whether it should be treated as a sample permalink.
       
   311  *                               Default false.
   316  * @return string The page permalink.
   312  * @return string The page permalink.
   317  */
   313  */
   318 function get_page_link( $post = false, $leavename = false, $sample = false ) {
   314 function get_page_link( $post = false, $leavename = false, $sample = false ) {
   319 	$post = get_post( $post );
   315 	$post = get_post( $post );
   320 
   316 
   322 		$link = home_url('/');
   318 		$link = home_url('/');
   323 	else
   319 	else
   324 		$link = _get_page_link( $post, $leavename, $sample );
   320 		$link = _get_page_link( $post, $leavename, $sample );
   325 
   321 
   326 	/**
   322 	/**
   327 	 * Filter the permalink for a page.
   323 	 * Filters the permalink for a page.
   328 	 *
   324 	 *
   329 	 * @since 1.5.0
   325 	 * @since 1.5.0
   330 	 *
   326 	 *
   331 	 * @param string $link    The page's permalink.
   327 	 * @param string $link    The page's permalink.
   332 	 * @param int    $post_id The ID of the page.
   328 	 * @param int    $post_id The ID of the page.
   334 	 */
   330 	 */
   335 	return apply_filters( 'page_link', $link, $post->ID, $sample );
   331 	return apply_filters( 'page_link', $link, $post->ID, $sample );
   336 }
   332 }
   337 
   333 
   338 /**
   334 /**
   339  * Retrieve the page permalink.
   335  * Retrieves the page permalink.
   340  *
   336  *
   341  * Ignores page_on_front. Internal use only.
   337  * Ignores page_on_front. Internal use only.
   342  *
   338  *
   343  * @since 2.1.0
   339  * @since 2.1.0
   344  * @access private
   340  * @access private
   345  *
   341  *
   346  * @param int|object $post Optional. Post ID or object.
   342  * @global WP_Rewrite $wp_rewrite
   347  * @param bool $leavename Optional. Leave name.
   343  *
   348  * @param bool $sample Optional. Sample permalink.
   344  * @param int|WP_Post $post      Optional. Post ID or object. Default uses the global `$post`.
       
   345  * @param bool        $leavename Optional. Whether to keep the page name. Default false.
       
   346  * @param bool        $sample    Optional. Whether it should be treated as a sample permalink.
       
   347  *                               Default false.
   349  * @return string The page permalink.
   348  * @return string The page permalink.
   350  */
   349  */
   351 function _get_page_link( $post = false, $leavename = false, $sample = false ) {
   350 function _get_page_link( $post = false, $leavename = false, $sample = false ) {
   352 	global $wp_rewrite;
   351 	global $wp_rewrite;
   353 
   352 
   367 	} else {
   366 	} else {
   368 		$link = home_url( '?page_id=' . $post->ID );
   367 		$link = home_url( '?page_id=' . $post->ID );
   369 	}
   368 	}
   370 
   369 
   371 	/**
   370 	/**
   372 	 * Filter the permalink for a non-page_on_front page.
   371 	 * Filters the permalink for a non-page_on_front page.
   373 	 *
   372 	 *
   374 	 * @since 2.1.0
   373 	 * @since 2.1.0
   375 	 *
   374 	 *
   376 	 * @param string $link    The page's permalink.
   375 	 * @param string $link    The page's permalink.
   377 	 * @param int    $post_id The ID of the page.
   376 	 * @param int    $post_id The ID of the page.
   378 	 */
   377 	 */
   379 	return apply_filters( '_get_page_link', $link, $post->ID );
   378 	return apply_filters( '_get_page_link', $link, $post->ID );
   380 }
   379 }
   381 
   380 
   382 /**
   381 /**
   383  * Retrieve permalink for attachment.
   382  * Retrieves the permalink for an attachment.
   384  *
   383  *
   385  * This can be used in the WordPress Loop or outside of it.
   384  * This can be used in the WordPress Loop or outside of it.
   386  *
   385  *
   387  * @since 2.0.0
   386  * @since 2.0.0
   388  *
   387  *
   389  * @param int|object $post Optional. Post ID or object.
   388  * @global WP_Rewrite $wp_rewrite
   390  * @param bool $leavename Optional. Leave name.
   389  *
       
   390  * @param int|object $post      Optional. Post ID or object. Default uses the global `$post`.
       
   391  * @param bool       $leavename Optional. Whether to keep the page name. Default false.
   391  * @return string The attachment permalink.
   392  * @return string The attachment permalink.
   392  */
   393  */
   393 function get_attachment_link( $post = null, $leavename = false ) {
   394 function get_attachment_link( $post = null, $leavename = false ) {
   394 	global $wp_rewrite;
   395 	global $wp_rewrite;
   395 
   396 
   396 	$link = false;
   397 	$link = false;
   397 
   398 
   398 	$post = get_post( $post );
   399 	$post = get_post( $post );
   399 	$parent = ( $post->post_parent > 0 && $post->post_parent != $post->ID ) ? get_post( $post->post_parent ) : false;
   400 	$parent = ( $post->post_parent > 0 && $post->post_parent != $post->ID ) ? get_post( $post->post_parent ) : false;
       
   401 	if ( $parent && ! in_array( $parent->post_type, get_post_types() ) ) {
       
   402 		$parent = false;
       
   403 	}
   400 
   404 
   401 	if ( $wp_rewrite->using_permalinks() && $parent ) {
   405 	if ( $wp_rewrite->using_permalinks() && $parent ) {
   402 		if ( 'page' == $parent->post_type )
   406 		if ( 'page' == $parent->post_type )
   403 			$parentlink = _get_page_link( $post->post_parent ); // Ignores page_on_front
   407 			$parentlink = _get_page_link( $post->post_parent ); // Ignores page_on_front
   404 		else
   408 		else
   412 		if ( strpos($parentlink, '?') === false )
   416 		if ( strpos($parentlink, '?') === false )
   413 			$link = user_trailingslashit( trailingslashit($parentlink) . '%postname%' );
   417 			$link = user_trailingslashit( trailingslashit($parentlink) . '%postname%' );
   414 
   418 
   415 		if ( ! $leavename )
   419 		if ( ! $leavename )
   416 			$link = str_replace( '%postname%', $name, $link );
   420 			$link = str_replace( '%postname%', $name, $link );
       
   421 	} elseif ( $wp_rewrite->using_permalinks() && ! $leavename ) {
       
   422 		$link = home_url( user_trailingslashit( $post->post_name ) );
   417 	}
   423 	}
   418 
   424 
   419 	if ( ! $link )
   425 	if ( ! $link )
   420 		$link = home_url( '/?attachment_id=' . $post->ID );
   426 		$link = home_url( '/?attachment_id=' . $post->ID );
   421 
   427 
   422 	/**
   428 	/**
   423 	 * Filter the permalink for an attachment.
   429 	 * Filters the permalink for an attachment.
   424 	 *
   430 	 *
   425 	 * @since 2.0.0
   431 	 * @since 2.0.0
   426 	 *
   432 	 *
   427 	 * @param string $link    The attachment's permalink.
   433 	 * @param string $link    The attachment's permalink.
   428 	 * @param int    $post_id Attachment ID.
   434 	 * @param int    $post_id Attachment ID.
   429 	 */
   435 	 */
   430 	return apply_filters( 'attachment_link', $link, $post->ID );
   436 	return apply_filters( 'attachment_link', $link, $post->ID );
   431 }
   437 }
   432 
   438 
   433 /**
   439 /**
   434  * Retrieve the permalink for the year archives.
   440  * Retrieves the permalink for the year archives.
   435  *
   441  *
   436  * @since 1.5.0
   442  * @since 1.5.0
       
   443  *
       
   444  * @global WP_Rewrite $wp_rewrite
   437  *
   445  *
   438  * @param int|bool $year False for current year or year for permalink.
   446  * @param int|bool $year False for current year or year for permalink.
   439  * @return string The permalink for the specified year archive.
   447  * @return string The permalink for the specified year archive.
   440  */
   448  */
   441 function get_year_link($year) {
   449 function get_year_link( $year ) {
   442 	global $wp_rewrite;
   450 	global $wp_rewrite;
   443 	if ( !$year )
   451 	if ( !$year )
   444 		$year = gmdate('Y', current_time('timestamp'));
   452 		$year = gmdate('Y', current_time('timestamp'));
   445 	$yearlink = $wp_rewrite->get_year_permastruct();
   453 	$yearlink = $wp_rewrite->get_year_permastruct();
   446 	if ( !empty($yearlink) ) {
   454 	if ( !empty($yearlink) ) {
   449 	} else {
   457 	} else {
   450 		$yearlink = home_url( '?m=' . $year );
   458 		$yearlink = home_url( '?m=' . $year );
   451 	}
   459 	}
   452 
   460 
   453 	/**
   461 	/**
   454 	 * Filter the year archive permalink.
   462 	 * Filters the year archive permalink.
   455 	 *
   463 	 *
   456 	 * @since 1.5.0
   464 	 * @since 1.5.0
   457 	 *
   465 	 *
   458 	 * @param string $yearlink Permalink for the year archive.
   466 	 * @param string $yearlink Permalink for the year archive.
   459 	 * @param int    $year     Year for the archive.
   467 	 * @param int    $year     Year for the archive.
   460 	 */
   468 	 */
   461 	return apply_filters( 'year_link', $yearlink, $year );
   469 	return apply_filters( 'year_link', $yearlink, $year );
   462 }
   470 }
   463 
   471 
   464 /**
   472 /**
   465  * Retrieve the permalink for the month archives with year.
   473  * Retrieves the permalink for the month archives with year.
   466  *
   474  *
   467  * @since 1.0.0
   475  * @since 1.0.0
   468  *
   476  *
   469  * @param bool|int $year False for current year. Integer of year.
   477  * @global WP_Rewrite $wp_rewrite
       
   478  *
       
   479  * @param bool|int $year  False for current year. Integer of year.
   470  * @param bool|int $month False for current month. Integer of month.
   480  * @param bool|int $month False for current month. Integer of month.
   471  * @return string The permalink for the specified month and year archive.
   481  * @return string The permalink for the specified month and year archive.
   472  */
   482  */
   473 function get_month_link($year, $month) {
   483 function get_month_link($year, $month) {
   474 	global $wp_rewrite;
   484 	global $wp_rewrite;
   484 	} else {
   494 	} else {
   485 		$monthlink = home_url( '?m=' . $year . zeroise( $month, 2 ) );
   495 		$monthlink = home_url( '?m=' . $year . zeroise( $month, 2 ) );
   486 	}
   496 	}
   487 
   497 
   488 	/**
   498 	/**
   489 	 * Filter the month archive permalink.
   499 	 * Filters the month archive permalink.
   490 	 *
   500 	 *
   491 	 * @since 1.5.0
   501 	 * @since 1.5.0
   492 	 *
   502 	 *
   493 	 * @param string $monthlink Permalink for the month archive.
   503 	 * @param string $monthlink Permalink for the month archive.
   494 	 * @param int    $year      Year for the archive.
   504 	 * @param int    $year      Year for the archive.
   496 	 */
   506 	 */
   497 	return apply_filters( 'month_link', $monthlink, $year, $month );
   507 	return apply_filters( 'month_link', $monthlink, $year, $month );
   498 }
   508 }
   499 
   509 
   500 /**
   510 /**
   501  * Retrieve the permalink for the day archives with year and month.
   511  * Retrieves the permalink for the day archives with year and month.
   502  *
   512  *
   503  * @since 1.0.0
   513  * @since 1.0.0
   504  *
   514  *
   505  * @param bool|int $year False for current year. Integer of year.
   515  * @global WP_Rewrite $wp_rewrite
       
   516  *
       
   517  * @param bool|int $year  False for current year. Integer of year.
   506  * @param bool|int $month False for current month. Integer of month.
   518  * @param bool|int $month False for current month. Integer of month.
   507  * @param bool|int $day False for current day. Integer of day.
   519  * @param bool|int $day   False for current day. Integer of day.
   508  * @return string The permalink for the specified day, month, and year archive.
   520  * @return string The permalink for the specified day, month, and year archive.
   509  */
   521  */
   510 function get_day_link($year, $month, $day) {
   522 function get_day_link($year, $month, $day) {
   511 	global $wp_rewrite;
   523 	global $wp_rewrite;
   512 	if ( !$year )
   524 	if ( !$year )
   525 	} else {
   537 	} else {
   526 		$daylink = home_url( '?m=' . $year . zeroise( $month, 2 ) . zeroise( $day, 2 ) );
   538 		$daylink = home_url( '?m=' . $year . zeroise( $month, 2 ) . zeroise( $day, 2 ) );
   527 	}
   539 	}
   528 
   540 
   529 	/**
   541 	/**
   530 	 * Filter the day archive permalink.
   542 	 * Filters the day archive permalink.
   531 	 *
   543 	 *
   532 	 * @since 1.5.0
   544 	 * @since 1.5.0
   533 	 *
   545 	 *
   534 	 * @param string $daylink Permalink for the day archive.
   546 	 * @param string $daylink Permalink for the day archive.
   535 	 * @param int    $year    Year for the archive.
   547 	 * @param int    $year    Year for the archive.
   538 	 */
   550 	 */
   539 	return apply_filters( 'day_link', $daylink, $year, $month, $day );
   551 	return apply_filters( 'day_link', $daylink, $year, $month, $day );
   540 }
   552 }
   541 
   553 
   542 /**
   554 /**
   543  * Display the permalink for the feed type.
   555  * Displays the permalink for the feed type.
   544  *
   556  *
   545  * @since 3.0.0
   557  * @since 3.0.0
   546  *
   558  *
   547  * @param string $anchor The link's anchor text.
   559  * @param string $anchor The link's anchor text.
   548  * @param string $feed Optional, defaults to default feed. Feed type.
   560  * @param string $feed   Optional. Feed type. Default empty.
   549  */
   561  */
   550 function the_feed_link( $anchor, $feed = '' ) {
   562 function the_feed_link( $anchor, $feed = '' ) {
   551 	$link = '<a href="' . esc_url( get_feed_link( $feed ) ) . '">' . $anchor . '</a>';
   563 	$link = '<a href="' . esc_url( get_feed_link( $feed ) ) . '">' . $anchor . '</a>';
   552 
   564 
   553 	/**
   565 	/**
   554 	 * Filter the feed link anchor tag.
   566 	 * Filters the feed link anchor tag.
   555 	 *
   567 	 *
   556 	 * @since 3.0.0
   568 	 * @since 3.0.0
   557 	 *
   569 	 *
   558 	 * @param string $link The complete anchor tag for a feed link.
   570 	 * @param string $link The complete anchor tag for a feed link.
   559 	 * @param string $feed The feed type, or an empty string for the
   571 	 * @param string $feed The feed type, or an empty string for the
   561 	 */
   573 	 */
   562 	echo apply_filters( 'the_feed_link', $link, $feed );
   574 	echo apply_filters( 'the_feed_link', $link, $feed );
   563 }
   575 }
   564 
   576 
   565 /**
   577 /**
   566  * Retrieve the permalink for the feed type.
   578  * Retrieves the permalink for the feed type.
   567  *
   579  *
   568  * @since 1.5.0
   580  * @since 1.5.0
   569  *
   581  *
   570  * @param string $feed Optional, defaults to default feed. Feed type.
   582  * @global WP_Rewrite $wp_rewrite
       
   583  *
       
   584  * @param string $feed Optional. Feed type. Default empty.
   571  * @return string The feed permalink.
   585  * @return string The feed permalink.
   572  */
   586  */
   573 function get_feed_link($feed = '') {
   587 function get_feed_link( $feed = '' ) {
   574 	global $wp_rewrite;
   588 	global $wp_rewrite;
   575 
   589 
   576 	$permalink = $wp_rewrite->get_feed_permastruct();
   590 	$permalink = $wp_rewrite->get_feed_permastruct();
   577 	if ( '' != $permalink ) {
   591 	if ( '' != $permalink ) {
   578 		if ( false !== strpos($feed, 'comments_') ) {
   592 		if ( false !== strpos($feed, 'comments_') ) {
   595 
   609 
   596 		$output = home_url("?feed={$feed}");
   610 		$output = home_url("?feed={$feed}");
   597 	}
   611 	}
   598 
   612 
   599 	/**
   613 	/**
   600 	 * Filter the feed type permalink.
   614 	 * Filters the feed type permalink.
   601 	 *
   615 	 *
   602 	 * @since 1.5.0
   616 	 * @since 1.5.0
   603 	 *
   617 	 *
   604 	 * @param string $output The feed permalink.
   618 	 * @param string $output The feed permalink.
   605 	 * @param string $feed   Feed type.
   619 	 * @param string $feed   Feed type.
   606 	 */
   620 	 */
   607 	return apply_filters( 'feed_link', $output, $feed );
   621 	return apply_filters( 'feed_link', $output, $feed );
   608 }
   622 }
   609 
   623 
   610 /**
   624 /**
   611  * Retrieve the permalink for the post comments feed.
   625  * Retrieves the permalink for the post comments feed.
   612  *
   626  *
   613  * @since 2.2.0
   627  * @since 2.2.0
   614  *
   628  *
   615  * @param int $post_id Optional. Post ID.
   629  * @param int    $post_id Optional. Post ID. Default is the ID of the global `$post`.
   616  * @param string $feed Optional. Feed type.
   630  * @param string $feed    Optional. Feed type. Default empty.
   617  * @return string The permalink for the comments feed for the given post.
   631  * @return string The permalink for the comments feed for the given post.
   618  */
   632  */
   619 function get_post_comments_feed_link($post_id = 0, $feed = '') {
   633 function get_post_comments_feed_link( $post_id = 0, $feed = '' ) {
   620 	$post_id = absint( $post_id );
   634 	$post_id = absint( $post_id );
   621 
   635 
   622 	if ( ! $post_id )
   636 	if ( ! $post_id )
   623 		$post_id = get_the_ID();
   637 		$post_id = get_the_ID();
   624 
   638 
   625 	if ( empty( $feed ) )
   639 	if ( empty( $feed ) )
   626 		$feed = get_default_feed();
   640 		$feed = get_default_feed();
       
   641 
       
   642 	$post = get_post( $post_id );
       
   643 	$unattached = 'attachment' === $post->post_type && 0 === (int) $post->post_parent;
   627 
   644 
   628 	if ( '' != get_option('permalink_structure') ) {
   645 	if ( '' != get_option('permalink_structure') ) {
   629 		if ( 'page' == get_option('show_on_front') && $post_id == get_option('page_on_front') )
   646 		if ( 'page' == get_option('show_on_front') && $post_id == get_option('page_on_front') )
   630 			$url = _get_page_link( $post_id );
   647 			$url = _get_page_link( $post_id );
   631 		else
   648 		else
   632 			$url = get_permalink($post_id);
   649 			$url = get_permalink($post_id);
   633 
   650 
   634 		$url = trailingslashit($url) . 'feed';
   651 		if ( $unattached ) {
   635 		if ( $feed != get_default_feed() )
   652 			$url =  home_url( '/feed/' );
   636 			$url .= "/$feed";
   653 			if ( $feed !== get_default_feed() ) {
   637 		$url = user_trailingslashit($url, 'single_feed');
   654 				$url .= "$feed/";
       
   655 			}
       
   656 			$url = add_query_arg( 'attachment_id', $post_id, $url );
       
   657 		} else {
       
   658 			$url = trailingslashit($url) . 'feed';
       
   659 			if ( $feed != get_default_feed() )
       
   660 				$url .= "/$feed";
       
   661 			$url = user_trailingslashit($url, 'single_feed');
       
   662 		}
   638 	} else {
   663 	} else {
   639 		$type = get_post_field('post_type', $post_id);
   664 		if ( $unattached ) {
   640 		if ( 'page' == $type )
   665 			$url = add_query_arg( array( 'feed' => $feed, 'attachment_id' => $post_id ), home_url( '/' ) );
       
   666 		} elseif ( 'page' == $post->post_type ) {
   641 			$url = add_query_arg( array( 'feed' => $feed, 'page_id' => $post_id ), home_url( '/' ) );
   667 			$url = add_query_arg( array( 'feed' => $feed, 'page_id' => $post_id ), home_url( '/' ) );
   642 		else
   668 		} else {
   643 			$url = add_query_arg( array( 'feed' => $feed, 'p' => $post_id ), home_url( '/' ) );
   669 			$url = add_query_arg( array( 'feed' => $feed, 'p' => $post_id ), home_url( '/' ) );
   644 	}
   670 		}
   645 
   671 	}
   646 	/**
   672 
   647 	 * Filter the post comments feed permalink.
   673 	/**
       
   674 	 * Filters the post comments feed permalink.
   648 	 *
   675 	 *
   649 	 * @since 1.5.1
   676 	 * @since 1.5.1
   650 	 *
   677 	 *
   651 	 * @param string $url Post comments feed permalink.
   678 	 * @param string $url Post comments feed permalink.
   652 	 */
   679 	 */
   653 	return apply_filters( 'post_comments_feed_link', $url );
   680 	return apply_filters( 'post_comments_feed_link', $url );
   654 }
   681 }
   655 
   682 
   656 /**
   683 /**
   657  * Display the comment feed link for a post.
   684  * Displays the comment feed link for a post.
   658  *
   685  *
   659  * Prints out the comment feed link for a post. Link text is placed in the
   686  * Prints out the comment feed link for a post. Link text is placed in the
   660  * anchor. If no link text is specified, default text is used. If no post ID is
   687  * anchor. If no link text is specified, default text is used. If no post ID is
   661  * specified, the current post is used.
   688  * specified, the current post is used.
   662  *
   689  *
   663  * @since 2.5.0
   690  * @since 2.5.0
   664  *
   691  *
   665  * @param string $link_text Descriptive text.
   692  * @param string $link_text Optional. Descriptive link text. Default 'Comments Feed'.
   666  * @param int $post_id Optional post ID. Default to current post.
   693  * @param int    $post_id   Optional. Post ID. Default is the ID of the global `$post`.
   667  * @param string $feed Optional. Feed format.
   694  * @param string $feed      Optional. Feed format. Default empty.
   668  * @return string Link to the comment feed for the current post.
   695  */
   669 */
       
   670 function post_comments_feed_link( $link_text = '', $post_id = '', $feed = '' ) {
   696 function post_comments_feed_link( $link_text = '', $post_id = '', $feed = '' ) {
   671 	$url = esc_url( get_post_comments_feed_link( $post_id, $feed ) );
   697 	$url = get_post_comments_feed_link( $post_id, $feed );
   672 	if ( empty($link_text) )
   698 	if ( empty( $link_text ) ) {
   673 		$link_text = __('Comments Feed');
   699 		$link_text = __('Comments Feed');
   674 
   700 	}
   675 	/**
   701 
   676 	 * Filter the post comment feed link anchor tag.
   702 	$link = '<a href="' . esc_url( $url ) . '">' . $link_text . '</a>';
       
   703 	/**
       
   704 	 * Filters the post comment feed link anchor tag.
   677 	 *
   705 	 *
   678 	 * @since 2.8.0
   706 	 * @since 2.8.0
   679 	 *
   707 	 *
   680 	 * @param string $link    The complete anchor tag for the comment feed link.
   708 	 * @param string $link    The complete anchor tag for the comment feed link.
   681 	 * @param int    $post_id Post ID.
   709 	 * @param int    $post_id Post ID.
   682 	 * @param string $feed    The feed type, or an empty string for the default feed type.
   710 	 * @param string $feed    The feed type, or an empty string for the default feed type.
   683 	 */
   711 	 */
   684 	echo apply_filters( 'post_comments_feed_link_html', "<a href='$url'>$link_text</a>", $post_id, $feed );
   712 	echo apply_filters( 'post_comments_feed_link_html', $link, $post_id, $feed );
   685 }
   713 }
   686 
   714 
   687 /**
   715 /**
   688  * Retrieve the feed link for a given author.
   716  * Retrieves the feed link for a given author.
   689  *
   717  *
   690  * Returns a link to the feed for all posts by a given author. A specific feed
   718  * Returns a link to the feed for all posts by a given author. A specific feed
   691  * can be requested or left blank to get the default feed.
   719  * can be requested or left blank to get the default feed.
   692  *
   720  *
   693  * @since 2.5.0
   721  * @since 2.5.0
   694  *
   722  *
   695  * @param int $author_id ID of an author.
   723  * @param int    $author_id Author ID.
   696  * @param string $feed Optional. Feed type.
   724  * @param string $feed      Optional. Feed type. Default empty.
   697  * @return string Link to the feed for the author specified by $author_id.
   725  * @return string Link to the feed for the author specified by $author_id.
   698 */
   726  */
   699 function get_author_feed_link( $author_id, $feed = '' ) {
   727 function get_author_feed_link( $author_id, $feed = '' ) {
   700 	$author_id = (int) $author_id;
   728 	$author_id = (int) $author_id;
   701 	$permalink_structure = get_option('permalink_structure');
   729 	$permalink_structure = get_option('permalink_structure');
   702 
   730 
   703 	if ( empty($feed) )
   731 	if ( empty($feed) )
   714 
   742 
   715 		$link = trailingslashit($link) . user_trailingslashit($feed_link, 'feed');
   743 		$link = trailingslashit($link) . user_trailingslashit($feed_link, 'feed');
   716 	}
   744 	}
   717 
   745 
   718 	/**
   746 	/**
   719 	 * Filter the feed link for a given author.
   747 	 * Filters the feed link for a given author.
   720 	 *
   748 	 *
   721 	 * @since 1.5.1
   749 	 * @since 1.5.1
   722 	 *
   750 	 *
   723 	 * @param string $link The author feed link.
   751 	 * @param string $link The author feed link.
   724 	 * @param string $feed Feed type.
   752 	 * @param string $feed Feed type.
   727 
   755 
   728 	return $link;
   756 	return $link;
   729 }
   757 }
   730 
   758 
   731 /**
   759 /**
   732  * Retrieve the feed link for a category.
   760  * Retrieves the feed link for a category.
   733  *
   761  *
   734  * Returns a link to the feed for all posts in a given category. A specific feed
   762  * Returns a link to the feed for all posts in a given category. A specific feed
   735  * can be requested or left blank to get the default feed.
   763  * can be requested or left blank to get the default feed.
   736  *
   764  *
   737  * @since 2.5.0
   765  * @since 2.5.0
   738  *
   766  *
   739  * @param int $cat_id ID of a category.
   767  * @param int    $cat_id Category ID.
   740  * @param string $feed Optional. Feed type.
   768  * @param string $feed   Optional. Feed type. Default empty.
   741  * @return string Link to the feed for the category specified by $cat_id.
   769  * @return string Link to the feed for the category specified by $cat_id.
   742 */
   770  */
   743 function get_category_feed_link($cat_id, $feed = '') {
   771 function get_category_feed_link( $cat_id, $feed = '' ) {
   744 	return get_term_feed_link($cat_id, 'category', $feed);
   772 	return get_term_feed_link( $cat_id, 'category', $feed );
   745 }
   773 }
   746 
   774 
   747 /**
   775 /**
   748  * Retrieve the feed link for a term.
   776  * Retrieves the feed link for a term.
   749  *
   777  *
   750  * Returns a link to the feed for all posts in a given term. A specific feed
   778  * Returns a link to the feed for all posts in a given term. A specific feed
   751  * can be requested or left blank to get the default feed.
   779  * can be requested or left blank to get the default feed.
   752  *
   780  *
   753  * @since 3.0.0
   781  * @since 3.0.0
   754  *
   782  *
   755  * @param int $term_id ID of a category.
   783  * @param int    $term_id  Term ID.
   756  * @param string $taxonomy Optional. Taxonomy of $term_id
   784  * @param string $taxonomy Optional. Taxonomy of `$term_id`. Default 'category'.
   757  * @param string $feed Optional. Feed type.
   785  * @param string $feed     Optional. Feed type. Default empty.
   758  * @return string Link to the feed for the term specified by $term_id and $taxonomy.
   786  * @return string|false Link to the feed for the term specified by $term_id and $taxonomy.
   759 */
   787  */
   760 function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) {
   788 function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) {
   761 	$term_id = ( int ) $term_id;
   789 	$term_id = ( int ) $term_id;
   762 
   790 
   763 	$term = get_term( $term_id, $taxonomy  );
   791 	$term = get_term( $term_id, $taxonomy  );
   764 
   792 
   790 		$link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' );
   818 		$link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' );
   791 	}
   819 	}
   792 
   820 
   793 	if ( 'category' == $taxonomy ) {
   821 	if ( 'category' == $taxonomy ) {
   794 		/**
   822 		/**
   795 		 * Filter the category feed link.
   823 		 * Filters the category feed link.
   796 		 *
   824 		 *
   797 		 * @since 1.5.1
   825 		 * @since 1.5.1
   798 		 *
   826 		 *
   799 		 * @param string $link The category feed link.
   827 		 * @param string $link The category feed link.
   800 		 * @param string $feed Feed type.
   828 		 * @param string $feed Feed type.
   801 		 */
   829 		 */
   802 		$link = apply_filters( 'category_feed_link', $link, $feed );
   830 		$link = apply_filters( 'category_feed_link', $link, $feed );
   803 	} elseif ( 'post_tag' == $taxonomy ) {
   831 	} elseif ( 'post_tag' == $taxonomy ) {
   804 		/**
   832 		/**
   805 		 * Filter the post tag feed link.
   833 		 * Filters the post tag feed link.
   806 		 *
   834 		 *
   807 		 * @since 2.3.0
   835 		 * @since 2.3.0
   808 		 *
   836 		 *
   809 		 * @param string $link The tag feed link.
   837 		 * @param string $link The tag feed link.
   810 		 * @param string $feed Feed type.
   838 		 * @param string $feed Feed type.
   811 		 */
   839 		 */
   812 		$link = apply_filters( 'tag_feed_link', $link, $feed );
   840 		$link = apply_filters( 'tag_feed_link', $link, $feed );
   813 	} else {
   841 	} else {
   814 		/**
   842 		/**
   815 		 * Filter the feed link for a taxonomy other than 'category' or 'post_tag'.
   843 		 * Filters the feed link for a taxonomy other than 'category' or 'post_tag'.
   816 		 *
   844 		 *
   817 		 * @since 3.0.0
   845 		 * @since 3.0.0
   818 		 *
   846 		 *
   819 		 * @param string $link The taxonomy feed link.
   847 		 * @param string $link The taxonomy feed link.
   820 		 * @param string $feed Feed type.
   848 		 * @param string $feed Feed type.
   821 		 * @param string $feed The taxonomy name.
   849 		 * @param string $taxonomy The taxonomy name.
   822 		 */
   850 		 */
   823 		$link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy );
   851 		$link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy );
   824 	}
   852 	}
   825 
   853 
   826 	return $link;
   854 	return $link;
   827 }
   855 }
   828 
   856 
   829 /**
   857 /**
   830  * Retrieve permalink for feed of tag.
   858  * Retrieves the permalink for a tag feed.
   831  *
   859  *
   832  * @since 2.3.0
   860  * @since 2.3.0
   833  *
   861  *
   834  * @param int $tag_id Tag ID.
   862  * @param int    $tag_id Tag ID.
   835  * @param string $feed Optional. Feed type.
   863  * @param string $feed   Optional. Feed type. Default empty.
   836  * @return string The feed permalink for the given tag.
   864  * @return string The feed permalink for the given tag.
   837  */
   865  */
   838 function get_tag_feed_link($tag_id, $feed = '') {
   866 function get_tag_feed_link( $tag_id, $feed = '' ) {
   839 	return get_term_feed_link($tag_id, 'post_tag', $feed);
   867 	return get_term_feed_link( $tag_id, 'post_tag', $feed );
   840 }
   868 }
   841 
   869 
   842 /**
   870 /**
   843  * Retrieve edit tag link.
   871  * Retrieves the edit link for a tag.
   844  *
   872  *
   845  * @since 2.7.0
   873  * @since 2.7.0
   846  *
   874  *
   847  * @param int $tag_id Tag ID
   875  * @param int    $tag_id   Tag ID.
   848  * @param string $taxonomy Taxonomy
   876  * @param string $taxonomy Optional. Taxonomy slug. Default 'post_tag'.
   849  * @return string The edit tag link URL for the given tag.
   877  * @return string The edit tag link URL for the given tag.
   850  */
   878  */
   851 function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) {
   879 function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) {
   852 	/**
   880 	/**
   853 	 * Filter the edit link for a tag (or term in another taxonomy).
   881 	 * Filters the edit link for a tag (or term in another taxonomy).
   854 	 *
   882 	 *
   855 	 * @since 2.7.0
   883 	 * @since 2.7.0
   856 	 *
   884 	 *
   857 	 * @param string $link The term edit link.
   885 	 * @param string $link The term edit link.
   858 	 */
   886 	 */
   859 	return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag_id, $taxonomy ) );
   887 	return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag_id, $taxonomy ) );
   860 }
   888 }
   861 
   889 
   862 /**
   890 /**
   863  * Display or retrieve edit tag link with formatting.
   891  * Displays or retrieves the edit link for a tag with formatting.
   864  *
   892  *
   865  * @since 2.7.0
   893  * @since 2.7.0
   866  *
   894  *
   867  * @param string $link Optional. Anchor text.
   895  * @param string  $link   Optional. Anchor text. Default empty.
   868  * @param string $before Optional. Display before edit link.
   896  * @param string  $before Optional. Display before edit link. Default empty.
   869  * @param string $after Optional. Display after edit link.
   897  * @param string  $after  Optional. Display after edit link. Default empty.
   870  * @param object $tag Tag object.
   898  * @param WP_Term $tag    Optional. Term object. If null, the queried object will be inspected.
   871  * @return string HTML content.
   899  *                        Default null.
   872  */
   900  */
   873 function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) {
   901 function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) {
   874 	$link = edit_term_link( $link, '', '', $tag, false );
   902 	$link = edit_term_link( $link, '', '', $tag, false );
   875 
   903 
   876 	/**
   904 	/**
   877 	 * Filter the anchor tag for the edit link for a tag (or term in another taxonomy).
   905 	 * Filters the anchor tag for the edit link for a tag (or term in another taxonomy).
   878 	 *
   906 	 *
   879 	 * @since 2.7.0
   907 	 * @since 2.7.0
   880 	 *
   908 	 *
   881 	 * @param string $link The anchor tag for the edit link.
   909 	 * @param string $link The anchor tag for the edit link.
   882 	 */
   910 	 */
   883 	echo $before . apply_filters( 'edit_tag_link', $link ) . $after;
   911 	echo $before . apply_filters( 'edit_tag_link', $link ) . $after;
   884 }
   912 }
   885 
   913 
   886 /**
   914 /**
   887  * Retrieve edit term url.
   915  * Retrieves the URL for editing a given term.
   888  *
   916  *
   889  * @since 3.1.0
   917  * @since 3.1.0
       
   918  * @since 4.5.0 The `$taxonomy` argument was made optional.
   890  *
   919  *
   891  * @param int    $term_id     Term ID.
   920  * @param int    $term_id     Term ID.
   892  * @param string $taxonomy    Taxonomy.
   921  * @param string $taxonomy    Optional. Taxonomy. Defaults to the taxonomy of the term identified
   893  * @param string $object_type The object type. Used to highlight the proper post type menu on the linked page.
   922  *                            by `$term_id`.
   894  *                            Defaults to the first object_type associated with the taxonomy.
   923  * @param string $object_type Optional. The object type. Used to highlight the proper post type
   895  * @return string The edit term link URL for the given term.
   924  *                            menu on the linked page. Defaults to the first object_type associated
   896  */
   925  *                            with the taxonomy.
   897 function get_edit_term_link( $term_id, $taxonomy, $object_type = '' ) {
   926  * @return string|null The edit term link URL for the given term, or null on failure.
   898 	$tax = get_taxonomy( $taxonomy );
   927  */
   899 	if ( !current_user_can( $tax->cap->edit_terms ) )
   928 function get_edit_term_link( $term_id, $taxonomy = '', $object_type = '' ) {
       
   929 	$term = get_term( $term_id, $taxonomy );
       
   930 	if ( ! $term || is_wp_error( $term ) ) {
   900 		return;
   931 		return;
   901 
   932 	}
   902 	$term = get_term( $term_id, $taxonomy );
   933 
       
   934 	$tax = get_taxonomy( $term->taxonomy );
       
   935 	if ( ! $tax || ! current_user_can( 'edit_term', $term->term_id ) ) {
       
   936 		return;
       
   937 	}
   903 
   938 
   904 	$args = array(
   939 	$args = array(
   905 		'action' => 'edit',
       
   906 		'taxonomy' => $taxonomy,
   940 		'taxonomy' => $taxonomy,
   907 		'tag_ID' => $term->term_id,
   941 		'tag_ID'   => $term->term_id,
   908 	);
   942 	);
   909 
   943 
   910 	if ( $object_type ) {
   944 	if ( $object_type ) {
   911 		$args['post_type'] = $object_type;
   945 		$args['post_type'] = $object_type;
   912 	} else if ( ! empty( $tax->object_type ) ) {
   946 	} elseif ( ! empty( $tax->object_type ) ) {
   913 		$args['post_type'] = reset( $tax->object_type );
   947 		$args['post_type'] = reset( $tax->object_type );
   914 	}
   948 	}
   915 
   949 
   916 	$location = add_query_arg( $args, admin_url( 'edit-tags.php' ) );
   950 	if ( $tax->show_ui ) {
   917 
   951 		$location = add_query_arg( $args, admin_url( 'term.php' ) );
   918 	/**
   952 	} else {
   919 	 * Filter the edit link for a term.
   953 		$location = '';
       
   954 	}
       
   955 
       
   956 	/**
       
   957 	 * Filters the edit link for a term.
   920 	 *
   958 	 *
   921 	 * @since 3.1.0
   959 	 * @since 3.1.0
   922 	 *
   960 	 *
   923 	 * @param string $location    The edit link.
   961 	 * @param string $location    The edit link.
   924 	 * @param int    $term_id     Term ID.
   962 	 * @param int    $term_id     Term ID.
   927 	 */
   965 	 */
   928 	return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type );
   966 	return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type );
   929 }
   967 }
   930 
   968 
   931 /**
   969 /**
   932  * Display or retrieve edit term link with formatting.
   970  * Displays or retrieves the edit term link with formatting.
   933  *
   971  *
   934  * @since 3.1.0
   972  * @since 3.1.0
   935  *
   973  *
   936  * @param string $link Optional. Anchor text.
   974  * @param string $link   Optional. Anchor text. Default empty.
   937  * @param string $before Optional. Display before edit link.
   975  * @param string $before Optional. Display before edit link. Default empty.
   938  * @param string $after Optional. Display after edit link.
   976  * @param string $after  Optional. Display after edit link. Default empty.
   939  * @param object $term Term object.
   977  * @param object $term   Optional. Term object. If null, the queried object will be inspected. Default null.
   940  * @return string HTML content.
   978  * @param bool   $echo   Optional. Whether or not to echo the return. Default true.
       
   979  * @return string|void HTML content.
   941  */
   980  */
   942 function edit_term_link( $link = '', $before = '', $after = '', $term = null, $echo = true ) {
   981 function edit_term_link( $link = '', $before = '', $after = '', $term = null, $echo = true ) {
   943 	if ( is_null( $term ) )
   982 	if ( is_null( $term ) )
   944 		$term = get_queried_object();
   983 		$term = get_queried_object();
   945 
   984 
   946 	if ( ! $term )
   985 	if ( ! $term )
   947 		return;
   986 		return;
   948 
   987 
   949 	$tax = get_taxonomy( $term->taxonomy );
   988 	$tax = get_taxonomy( $term->taxonomy );
   950 	if ( ! current_user_can( $tax->cap->edit_terms ) )
   989 	if ( ! current_user_can( 'edit_term', $term->term_id ) ) {
   951 		return;
   990 		return;
       
   991 	}
   952 
   992 
   953 	if ( empty( $link ) )
   993 	if ( empty( $link ) )
   954 		$link = __('Edit This');
   994 		$link = __('Edit This');
   955 
   995 
   956 	$link = '<a href="' . get_edit_term_link( $term->term_id, $term->taxonomy ) . '">' . $link . '</a>';
   996 	$link = '<a href="' . get_edit_term_link( $term->term_id, $term->taxonomy ) . '">' . $link . '</a>';
   957 
   997 
   958 	/**
   998 	/**
   959 	 * Filter the anchor tag for the edit link of a term.
   999 	 * Filters the anchor tag for the edit link of a term.
   960 	 *
  1000 	 *
   961 	 * @since 3.1.0
  1001 	 * @since 3.1.0
   962 	 *
  1002 	 *
   963 	 * @param string $link    The anchor tag for the edit link.
  1003 	 * @param string $link    The anchor tag for the edit link.
   964 	 * @param int    $term_id Term ID.
  1004 	 * @param int    $term_id Term ID.
   970 	else
  1010 	else
   971 		return $link;
  1011 		return $link;
   972 }
  1012 }
   973 
  1013 
   974 /**
  1014 /**
   975  * Retrieve permalink for search.
  1015  * Retrieves the permalink for a search.
   976  *
  1016  *
   977  * @since  3.0.0
  1017  * @since  3.0.0
   978  *
  1018  *
   979  * @param string $query Optional. The query string to use. If empty the current query is used.
  1019  * @global WP_Rewrite $wp_rewrite
       
  1020  *
       
  1021  * @param string $query Optional. The query string to use. If empty the current query is used. Default empty.
   980  * @return string The search permalink.
  1022  * @return string The search permalink.
   981  */
  1023  */
   982 function get_search_link( $query = '' ) {
  1024 function get_search_link( $query = '' ) {
   983 	global $wp_rewrite;
  1025 	global $wp_rewrite;
   984 
  1026 
   991 
  1033 
   992 	if ( empty( $permastruct ) ) {
  1034 	if ( empty( $permastruct ) ) {
   993 		$link = home_url('?s=' . urlencode($search) );
  1035 		$link = home_url('?s=' . urlencode($search) );
   994 	} else {
  1036 	} else {
   995 		$search = urlencode($search);
  1037 		$search = urlencode($search);
   996 		$search = str_replace('%2F', '/', $search); // %2F(/) is not valid within a URL, send it unencoded.
  1038 		$search = str_replace('%2F', '/', $search); // %2F(/) is not valid within a URL, send it un-encoded.
   997 		$link = str_replace( '%search%', $search, $permastruct );
  1039 		$link = str_replace( '%search%', $search, $permastruct );
   998 		$link = home_url( user_trailingslashit( $link, 'search' ) );
  1040 		$link = home_url( user_trailingslashit( $link, 'search' ) );
   999 	}
  1041 	}
  1000 
  1042 
  1001 	/**
  1043 	/**
  1002 	 * Filter the search permalink.
  1044 	 * Filters the search permalink.
  1003 	 *
  1045 	 *
  1004 	 * @since 3.0.0
  1046 	 * @since 3.0.0
  1005 	 *
  1047 	 *
  1006 	 * @param string $link   Search permalink.
  1048 	 * @param string $link   Search permalink.
  1007 	 * @param string $search The URL-encoded search term.
  1049 	 * @param string $search The URL-encoded search term.
  1008 	 */
  1050 	 */
  1009 	return apply_filters( 'search_link', $link, $search );
  1051 	return apply_filters( 'search_link', $link, $search );
  1010 }
  1052 }
  1011 
  1053 
  1012 /**
  1054 /**
  1013  * Retrieve the permalink for the feed of the search results.
  1055  * Retrieves the permalink for the search results feed.
  1014  *
  1056  *
  1015  * @since 2.5.0
  1057  * @since 2.5.0
  1016  *
  1058  *
  1017  * @param string $search_query Optional. Search query.
  1059  * @global WP_Rewrite $wp_rewrite
  1018  * @param string $feed Optional. Feed type.
  1060  *
       
  1061  * @param string $search_query Optional. Search query. Default empty.
       
  1062  * @param string $feed         Optional. Feed type. Default empty.
  1019  * @return string The search results feed permalink.
  1063  * @return string The search results feed permalink.
  1020  */
  1064  */
  1021 function get_search_feed_link($search_query = '', $feed = '') {
  1065 function get_search_feed_link($search_query = '', $feed = '') {
  1022 	global $wp_rewrite;
  1066 	global $wp_rewrite;
  1023 	$link = get_search_link($search_query);
  1067 	$link = get_search_link($search_query);
  1033 		$link = trailingslashit($link);
  1077 		$link = trailingslashit($link);
  1034 		$link .= "feed/$feed/";
  1078 		$link .= "feed/$feed/";
  1035 	}
  1079 	}
  1036 
  1080 
  1037 	/**
  1081 	/**
  1038 	 * Filter the search feed link.
  1082 	 * Filters the search feed link.
  1039 	 *
  1083 	 *
  1040 	 * @since 2.5.0
  1084 	 * @since 2.5.0
  1041 	 *
  1085 	 *
  1042 	 * @param string $link Search feed link.
  1086 	 * @param string $link Search feed link.
  1043 	 * @param string $feed Feed type.
  1087 	 * @param string $feed Feed type.
  1044 	 * @param string $type The search type. One of 'posts' or 'comments'.
  1088 	 * @param string $type The search type. One of 'posts' or 'comments'.
  1045 	 */
  1089 	 */
  1046 	$link = apply_filters( 'search_feed_link', $link, $feed, 'posts' );
  1090 	return apply_filters( 'search_feed_link', $link, $feed, 'posts' );
  1047 
  1091 }
  1048 	return $link;
  1092 
  1049 }
  1093 /**
  1050 
  1094  * Retrieves the permalink for the search results comments feed.
  1051 /**
       
  1052  * Retrieve the permalink for the comments feed of the search results.
       
  1053  *
  1095  *
  1054  * @since 2.5.0
  1096  * @since 2.5.0
  1055  *
  1097  *
  1056  * @param string $search_query Optional. Search query.
  1098  * @global WP_Rewrite $wp_rewrite
  1057  * @param string $feed Optional. Feed type.
  1099  *
       
  1100  * @param string $search_query Optional. Search query. Default empty.
       
  1101  * @param string $feed         Optional. Feed type. Default empty.
  1058  * @return string The comments feed search results permalink.
  1102  * @return string The comments feed search results permalink.
  1059  */
  1103  */
  1060 function get_search_comments_feed_link($search_query = '', $feed = '') {
  1104 function get_search_comments_feed_link($search_query = '', $feed = '') {
  1061 	global $wp_rewrite;
  1105 	global $wp_rewrite;
  1062 
  1106 
  1071 		$link = add_query_arg('feed', 'comments-' . $feed, $link);
  1115 		$link = add_query_arg('feed', 'comments-' . $feed, $link);
  1072 	else
  1116 	else
  1073 		$link = add_query_arg('withcomments', 1, $link);
  1117 		$link = add_query_arg('withcomments', 1, $link);
  1074 
  1118 
  1075 	/** This filter is documented in wp-includes/link-template.php */
  1119 	/** This filter is documented in wp-includes/link-template.php */
  1076 	$link = apply_filters('search_feed_link', $link, $feed, 'comments');
  1120 	return apply_filters( 'search_feed_link', $link, $feed, 'comments' );
  1077 
  1121 }
  1078 	return $link;
  1122 
  1079 }
  1123 /**
  1080 
  1124  * Retrieves the permalink for a post type archive.
  1081 /**
       
  1082  * Retrieve the permalink for a post type archive.
       
  1083  *
  1125  *
  1084  * @since 3.1.0
  1126  * @since 3.1.0
  1085  *
  1127  * @since 4.5.0 Support for posts was added.
  1086  * @param string $post_type Post type
  1128  *
  1087  * @return string The post type archive permalink.
  1129  * @global WP_Rewrite $wp_rewrite
       
  1130  *
       
  1131  * @param string $post_type Post type.
       
  1132  * @return string|false The post type archive permalink.
  1088  */
  1133  */
  1089 function get_post_type_archive_link( $post_type ) {
  1134 function get_post_type_archive_link( $post_type ) {
  1090 	global $wp_rewrite;
  1135 	global $wp_rewrite;
  1091 	if ( ! $post_type_obj = get_post_type_object( $post_type ) )
  1136 	if ( ! $post_type_obj = get_post_type_object( $post_type ) )
  1092 		return false;
  1137 		return false;
       
  1138 
       
  1139 	if ( 'post' === $post_type ) {
       
  1140 		$show_on_front = get_option( 'show_on_front' );
       
  1141 		$page_for_posts  = get_option( 'page_for_posts' );
       
  1142 
       
  1143 		if ( 'page' == $show_on_front && $page_for_posts ) {
       
  1144 			$link = get_permalink( $page_for_posts );
       
  1145 		} else {
       
  1146 			$link = get_home_url();
       
  1147 		}
       
  1148 		/** This filter is documented in wp-includes/link-template.php */
       
  1149 		return apply_filters( 'post_type_archive_link', $link, $post_type );
       
  1150 	}
  1093 
  1151 
  1094 	if ( ! $post_type_obj->has_archive )
  1152 	if ( ! $post_type_obj->has_archive )
  1095 		return false;
  1153 		return false;
  1096 
  1154 
  1097 	if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) ) {
  1155 	if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) ) {
  1104 	} else {
  1162 	} else {
  1105 		$link = home_url( '?post_type=' . $post_type );
  1163 		$link = home_url( '?post_type=' . $post_type );
  1106 	}
  1164 	}
  1107 
  1165 
  1108 	/**
  1166 	/**
  1109 	 * Filter the post type archive permalink.
  1167 	 * Filters the post type archive permalink.
  1110 	 *
  1168 	 *
  1111 	 * @since 3.1.0
  1169 	 * @since 3.1.0
  1112 	 *
  1170 	 *
  1113 	 * @param string $link      The post type archive permalink.
  1171 	 * @param string $link      The post type archive permalink.
  1114 	 * @param string $post_type Post type name.
  1172 	 * @param string $post_type Post type name.
  1115 	 */
  1173 	 */
  1116 	return apply_filters( 'post_type_archive_link', $link, $post_type );
  1174 	return apply_filters( 'post_type_archive_link', $link, $post_type );
  1117 }
  1175 }
  1118 
  1176 
  1119 /**
  1177 /**
  1120  * Retrieve the permalink for a post type archive feed.
  1178  * Retrieves the permalink for a post type archive feed.
  1121  *
  1179  *
  1122  * @since 3.1.0
  1180  * @since 3.1.0
  1123  *
  1181  *
  1124  * @param string $post_type Post type
  1182  * @param string $post_type Post type
  1125  * @param string $feed Optional. Feed type
  1183  * @param string $feed      Optional. Feed type. Default empty.
  1126  * @return string The post type feed permalink.
  1184  * @return string|false The post type feed permalink.
  1127  */
  1185  */
  1128 function get_post_type_archive_feed_link( $post_type, $feed = '' ) {
  1186 function get_post_type_archive_feed_link( $post_type, $feed = '' ) {
  1129 	$default_feed = get_default_feed();
  1187 	$default_feed = get_default_feed();
  1130 	if ( empty( $feed ) )
  1188 	if ( empty( $feed ) )
  1131 		$feed = $default_feed;
  1189 		$feed = $default_feed;
  1142 	} else {
  1200 	} else {
  1143 		$link = add_query_arg( 'feed', $feed, $link );
  1201 		$link = add_query_arg( 'feed', $feed, $link );
  1144 	}
  1202 	}
  1145 
  1203 
  1146 	/**
  1204 	/**
  1147 	 * Filter the post type archive feed link.
  1205 	 * Filters the post type archive feed link.
  1148 	 *
  1206 	 *
  1149 	 * @since 3.1.0
  1207 	 * @since 3.1.0
  1150 	 *
  1208 	 *
  1151 	 * @param string $link The post type archive feed link.
  1209 	 * @param string $link The post type archive feed link.
  1152 	 * @param string $feed Feed type.
  1210 	 * @param string $feed Feed type.
  1153 	 */
  1211 	 */
  1154 	return apply_filters( 'post_type_archive_feed_link', $link, $feed );
  1212 	return apply_filters( 'post_type_archive_feed_link', $link, $feed );
  1155 }
  1213 }
  1156 
  1214 
  1157 /**
  1215 /**
  1158  * Retrieve edit posts link for post.
  1216  * Retrieves the URL used for the post preview.
       
  1217  *
       
  1218  * Allows additional query args to be appended.
       
  1219  *
       
  1220  * @since 4.4.0
       
  1221  *
       
  1222  * @param int|WP_Post $post         Optional. Post ID or `WP_Post` object. Defaults to global `$post`.
       
  1223  * @param array       $query_args   Optional. Array of additional query args to be appended to the link.
       
  1224  *                                  Default empty array.
       
  1225  * @param string      $preview_link Optional. Base preview link to be used if it should differ from the
       
  1226  *                                  post permalink. Default empty.
       
  1227  * @return string|null URL used for the post preview, or null if the post does not exist.
       
  1228  */
       
  1229 function get_preview_post_link( $post = null, $query_args = array(), $preview_link = '' ) {
       
  1230 	$post = get_post( $post );
       
  1231 	if ( ! $post ) {
       
  1232 		return;
       
  1233 	}
       
  1234 
       
  1235 	$post_type_object = get_post_type_object( $post->post_type );
       
  1236 	if ( is_post_type_viewable( $post_type_object ) ) {
       
  1237 		if ( ! $preview_link ) {
       
  1238 			$preview_link = set_url_scheme( get_permalink( $post ) );
       
  1239 		}
       
  1240 
       
  1241 		$query_args['preview'] = 'true';
       
  1242 		$preview_link = add_query_arg( $query_args, $preview_link );
       
  1243 	}
       
  1244 
       
  1245 	/**
       
  1246 	 * Filters the URL used for a post preview.
       
  1247 	 *
       
  1248 	 * @since 2.0.5
       
  1249 	 * @since 4.0.0 Added the `$post` parameter.
       
  1250 	 *
       
  1251 	 * @param string  $preview_link URL used for the post preview.
       
  1252 	 * @param WP_Post $post         Post object.
       
  1253 	 */
       
  1254 	return apply_filters( 'preview_post_link', $preview_link, $post );
       
  1255 }
       
  1256 
       
  1257 /**
       
  1258  * Retrieves the edit post link for post.
  1159  *
  1259  *
  1160  * Can be used within the WordPress loop or outside of it. Can be used with
  1260  * Can be used within the WordPress loop or outside of it. Can be used with
  1161  * pages, posts, attachments, and revisions.
  1261  * pages, posts, attachments, and revisions.
  1162  *
  1262  *
  1163  * @since 2.3.0
  1263  * @since 2.3.0
  1164  *
  1264  *
  1165  * @param int $id Optional. Post ID.
  1265  * @param int|WP_Post $id      Optional. Post ID or post object. Default is the global `$post`.
  1166  * @param string $context Optional, defaults to display. How to write the '&', defaults to '&amp;'.
  1266  * @param string      $context Optional. How to output the '&' character. Default '&amp;'.
  1167  * @return string The edit post link for the given post.
  1267  * @return string|null The edit post link for the given post. null if the post type is invalid or does
       
  1268  *                     not allow an editing UI.
  1168  */
  1269  */
  1169 function get_edit_post_link( $id = 0, $context = 'display' ) {
  1270 function get_edit_post_link( $id = 0, $context = 'display' ) {
  1170 	if ( ! $post = get_post( $id ) )
  1271 	if ( ! $post = get_post( $id ) )
  1171 		return;
  1272 		return;
  1172 
  1273 
  1182 		return;
  1283 		return;
  1183 
  1284 
  1184 	if ( !current_user_can( 'edit_post', $post->ID ) )
  1285 	if ( !current_user_can( 'edit_post', $post->ID ) )
  1185 		return;
  1286 		return;
  1186 
  1287 
  1187 	/**
  1288 	if ( $post_type_object->_edit_link ) {
  1188 	 * Filter the post edit link.
  1289 		$link = admin_url( sprintf( $post_type_object->_edit_link . $action, $post->ID ) );
       
  1290 	} else {
       
  1291 		$link = '';
       
  1292 	}
       
  1293 
       
  1294 	/**
       
  1295 	 * Filters the post edit link.
  1189 	 *
  1296 	 *
  1190 	 * @since 2.3.0
  1297 	 * @since 2.3.0
  1191 	 *
  1298 	 *
  1192 	 * @param string $link    The edit link.
  1299 	 * @param string $link    The edit link.
  1193 	 * @param int    $post_id Post ID.
  1300 	 * @param int    $post_id Post ID.
  1194 	 * @param string $context The link context. If set to 'display' then ampersands
  1301 	 * @param string $context The link context. If set to 'display' then ampersands
  1195 	 *                        are encoded.
  1302 	 *                        are encoded.
  1196 	 */
  1303 	 */
  1197 	return apply_filters( 'get_edit_post_link', admin_url( sprintf( $post_type_object->_edit_link . $action, $post->ID ) ), $post->ID, $context );
  1304 	return apply_filters( 'get_edit_post_link', $link, $post->ID, $context );
  1198 }
  1305 }
  1199 
  1306 
  1200 /**
  1307 /**
  1201  * Display edit post link for post.
  1308  * Displays the edit post link for post.
  1202  *
  1309  *
  1203  * @since 1.0.0
  1310  * @since 1.0.0
  1204  *
  1311  * @since 4.4.0 The `$class` argument was added.
  1205  * @param string $text Optional. Anchor text.
  1312  *
  1206  * @param string $before Optional. Display before edit link.
  1313  * @param string      $text   Optional. Anchor text. If null, default is 'Edit This'. Default null.
  1207  * @param string $after Optional. Display after edit link.
  1314  * @param string      $before Optional. Display before edit link. Default empty.
  1208  * @param int $id Optional. Post ID.
  1315  * @param string      $after  Optional. Display after edit link. Default empty.
  1209  */
  1316  * @param int|WP_Post $id     Optional. Post ID or post object. Default is the global `$post`.
  1210 function edit_post_link( $text = null, $before = '', $after = '', $id = 0 ) {
  1317  * @param string      $class  Optional. Add custom class to link. Default 'post-edit-link'.
       
  1318  */
       
  1319 function edit_post_link( $text = null, $before = '', $after = '', $id = 0, $class = 'post-edit-link' ) {
  1211 	if ( ! $post = get_post( $id ) ) {
  1320 	if ( ! $post = get_post( $id ) ) {
  1212 		return;
  1321 		return;
  1213 	}
  1322 	}
  1214 
  1323 
  1215 	if ( ! $url = get_edit_post_link( $post->ID ) ) {
  1324 	if ( ! $url = get_edit_post_link( $post->ID ) ) {
  1218 
  1327 
  1219 	if ( null === $text ) {
  1328 	if ( null === $text ) {
  1220 		$text = __( 'Edit This' );
  1329 		$text = __( 'Edit This' );
  1221 	}
  1330 	}
  1222 
  1331 
  1223 	$link = '<a class="post-edit-link" href="' . $url . '">' . $text . '</a>';
  1332 	$link = '<a class="' . esc_attr( $class ) . '" href="' . esc_url( $url ) . '">' . $text . '</a>';
  1224 
  1333 
  1225 	/**
  1334 	/**
  1226 	 * Filter the post edit link anchor tag.
  1335 	 * Filters the post edit link anchor tag.
  1227 	 *
  1336 	 *
  1228 	 * @since 2.3.0
  1337 	 * @since 2.3.0
  1229 	 *
  1338 	 *
  1230 	 * @param string $link    Anchor tag for the edit link.
  1339 	 * @param string $link    Anchor tag for the edit link.
  1231 	 * @param int    $post_id Post ID.
  1340 	 * @param int    $post_id Post ID.
  1233 	 */
  1342 	 */
  1234 	echo $before . apply_filters( 'edit_post_link', $link, $post->ID, $text ) . $after;
  1343 	echo $before . apply_filters( 'edit_post_link', $link, $post->ID, $text ) . $after;
  1235 }
  1344 }
  1236 
  1345 
  1237 /**
  1346 /**
  1238  * Retrieve delete posts link for post.
  1347  * Retrieves the delete posts link for post.
  1239  *
  1348  *
  1240  * Can be used within the WordPress loop or outside of it, with any post type.
  1349  * Can be used within the WordPress loop or outside of it, with any post type.
  1241  *
  1350  *
  1242  * @since 2.9.0
  1351  * @since 2.9.0
  1243  *
  1352  *
  1244  * @param int $id Optional. Post ID.
  1353  * @param int|WP_Post $id           Optional. Post ID or post object. Default is the global `$post`.
  1245  * @param string $deprecated Not used.
  1354  * @param string      $deprecated   Not used.
  1246  * @param bool $force_delete Whether to bypass trash and force deletion. Default is false.
  1355  * @param bool        $force_delete Optional. Whether to bypass trash and force deletion. Default false.
  1247  * @return string The delete post link URL for the given post.
  1356  * @return string|void The delete post link URL for the given post.
  1248  */
  1357  */
  1249 function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false ) {
  1358 function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false ) {
  1250 	if ( ! empty( $deprecated ) )
  1359 	if ( ! empty( $deprecated ) )
  1251 		_deprecated_argument( __FUNCTION__, '3.0' );
  1360 		_deprecated_argument( __FUNCTION__, '3.0.0' );
  1252 
  1361 
  1253 	if ( !$post = get_post( $id ) )
  1362 	if ( !$post = get_post( $id ) )
  1254 		return;
  1363 		return;
  1255 
  1364 
  1256 	$post_type_object = get_post_type_object( $post->post_type );
  1365 	$post_type_object = get_post_type_object( $post->post_type );
  1263 	$action = ( $force_delete || !EMPTY_TRASH_DAYS ) ? 'delete' : 'trash';
  1372 	$action = ( $force_delete || !EMPTY_TRASH_DAYS ) ? 'delete' : 'trash';
  1264 
  1373 
  1265 	$delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) );
  1374 	$delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) );
  1266 
  1375 
  1267 	/**
  1376 	/**
  1268 	 * Filter the post delete link.
  1377 	 * Filters the post delete link.
  1269 	 *
  1378 	 *
  1270 	 * @since 2.9.0
  1379 	 * @since 2.9.0
  1271 	 *
  1380 	 *
  1272 	 * @param string $link         The delete link.
  1381 	 * @param string $link         The delete link.
  1273 	 * @param int    $post_id      Post ID.
  1382 	 * @param int    $post_id      Post ID.
  1275 	 */
  1384 	 */
  1276 	return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-post_{$post->ID}" ), $post->ID, $force_delete );
  1385 	return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-post_{$post->ID}" ), $post->ID, $force_delete );
  1277 }
  1386 }
  1278 
  1387 
  1279 /**
  1388 /**
  1280  * Retrieve edit comment link.
  1389  * Retrieves the edit comment link.
  1281  *
  1390  *
  1282  * @since 2.3.0
  1391  * @since 2.3.0
  1283  *
  1392  *
  1284  * @param int $comment_id Optional. Comment ID.
  1393  * @param int|WP_Comment $comment_id Optional. Comment ID or WP_Comment object.
  1285  * @return string The edit comment link URL for the given comment.
  1394  * @return string|void The edit comment link URL for the given comment.
  1286  */
  1395  */
  1287 function get_edit_comment_link( $comment_id = 0 ) {
  1396 function get_edit_comment_link( $comment_id = 0 ) {
  1288 	$comment = get_comment( $comment_id );
  1397 	$comment = get_comment( $comment_id );
  1289 
  1398 
  1290 	if ( !current_user_can( 'edit_comment', $comment->comment_ID ) )
  1399 	if ( !current_user_can( 'edit_comment', $comment->comment_ID ) )
  1291 		return;
  1400 		return;
  1292 
  1401 
  1293 	$location = admin_url('comment.php?action=editcomment&amp;c=') . $comment->comment_ID;
  1402 	$location = admin_url('comment.php?action=editcomment&amp;c=') . $comment->comment_ID;
  1294 
  1403 
  1295 	/**
  1404 	/**
  1296 	 * Filter the comment edit link.
  1405 	 * Filters the comment edit link.
  1297 	 *
  1406 	 *
  1298 	 * @since 2.3.0
  1407 	 * @since 2.3.0
  1299 	 *
  1408 	 *
  1300 	 * @param string $location The edit link.
  1409 	 * @param string $location The edit link.
  1301 	 */
  1410 	 */
  1302 	return apply_filters( 'get_edit_comment_link', $location );
  1411 	return apply_filters( 'get_edit_comment_link', $location );
  1303 }
  1412 }
  1304 
  1413 
  1305 /**
  1414 /**
  1306  * Display edit comment link with formatting.
  1415  * Displays the edit comment link with formatting.
  1307  *
  1416  *
  1308  * @since 1.0.0
  1417  * @since 1.0.0
  1309  *
  1418  *
  1310  * @param string $text Optional. Anchor text.
  1419  * @param string $text   Optional. Anchor text. If null, default is 'Edit This'. Default null.
  1311  * @param string $before Optional. Display before edit link.
  1420  * @param string $before Optional. Display before edit link. Default empty.
  1312  * @param string $after Optional. Display after edit link.
  1421  * @param string $after  Optional. Display after edit link. Default empty.
  1313  */
  1422  */
  1314 function edit_comment_link( $text = null, $before = '', $after = '' ) {
  1423 function edit_comment_link( $text = null, $before = '', $after = '' ) {
  1315 	global $comment;
  1424 	$comment = get_comment();
  1316 
  1425 
  1317 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
  1426 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
  1318 		return;
  1427 		return;
  1319 	}
  1428 	}
  1320 
  1429 
  1321 	if ( null === $text ) {
  1430 	if ( null === $text ) {
  1322 		$text = __( 'Edit This' );
  1431 		$text = __( 'Edit This' );
  1323 	}
  1432 	}
  1324 
  1433 
  1325 	$link = '<a class="comment-edit-link" href="' . get_edit_comment_link( $comment->comment_ID ) . '">' . $text . '</a>';
  1434 	$link = '<a class="comment-edit-link" href="' . esc_url( get_edit_comment_link( $comment ) ) . '">' . $text . '</a>';
  1326 
  1435 
  1327 	/**
  1436 	/**
  1328 	 * Filter the comment edit link anchor tag.
  1437 	 * Filters the comment edit link anchor tag.
  1329 	 *
  1438 	 *
  1330 	 * @since 2.3.0
  1439 	 * @since 2.3.0
  1331 	 *
  1440 	 *
  1332 	 * @param string $link       Anchor tag for the edit link.
  1441 	 * @param string $link       Anchor tag for the edit link.
  1333 	 * @param int    $comment_id Comment ID.
  1442 	 * @param int    $comment_id Comment ID.
  1335 	 */
  1444 	 */
  1336 	echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID, $text ) . $after;
  1445 	echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID, $text ) . $after;
  1337 }
  1446 }
  1338 
  1447 
  1339 /**
  1448 /**
  1340  * Display edit bookmark (literally a URL external to blog) link.
  1449  * Displays the edit bookmark link.
  1341  *
  1450  *
  1342  * @since 2.7.0
  1451  * @since 2.7.0
  1343  *
  1452  *
  1344  * @param int|stdClass $link Optional. Bookmark ID.
  1453  * @param int|stdClass $link Optional. Bookmark ID. Default is the id of the current bookmark.
  1345  * @return string The edit bookmark link URL.
  1454  * @return string|void The edit bookmark link URL.
  1346  */
  1455  */
  1347 function get_edit_bookmark_link( $link = 0 ) {
  1456 function get_edit_bookmark_link( $link = 0 ) {
  1348 	$link = get_bookmark( $link );
  1457 	$link = get_bookmark( $link );
  1349 
  1458 
  1350 	if ( !current_user_can('manage_links') )
  1459 	if ( !current_user_can('manage_links') )
  1351 		return;
  1460 		return;
  1352 
  1461 
  1353 	$location = admin_url('link.php?action=edit&amp;link_id=') . $link->link_id;
  1462 	$location = admin_url('link.php?action=edit&amp;link_id=') . $link->link_id;
  1354 
  1463 
  1355 	/**
  1464 	/**
  1356 	 * Filter the bookmark (link) edit link.
  1465 	 * Filters the bookmark edit link.
  1357 	 *
  1466 	 *
  1358 	 * @since 2.7.0
  1467 	 * @since 2.7.0
  1359 	 *
  1468 	 *
  1360 	 * @param string $location The edit link.
  1469 	 * @param string $location The edit link.
  1361 	 * @param int    $link_id  Bookmark ID.
  1470 	 * @param int    $link_id  Bookmark ID.
  1362 	 */
  1471 	 */
  1363 	return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id );
  1472 	return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id );
  1364 }
  1473 }
  1365 
  1474 
  1366 /**
  1475 /**
  1367  * Display edit bookmark (literally a URL external to blog) link anchor content.
  1476  * Displays the edit bookmark link anchor content.
  1368  *
  1477  *
  1369  * @since 2.7.0
  1478  * @since 2.7.0
  1370  *
  1479  *
  1371  * @param string $link Optional. Anchor text.
  1480  * @param string $link     Optional. Anchor text. Default empty.
  1372  * @param string $before Optional. Display before edit link.
  1481  * @param string $before   Optional. Display before edit link. Default empty.
  1373  * @param string $after Optional. Display after edit link.
  1482  * @param string $after    Optional. Display after edit link. Default empty.
  1374  * @param int $bookmark Optional. Bookmark ID.
  1483  * @param int    $bookmark Optional. Bookmark ID. Default is the current bookmark.
  1375  */
  1484  */
  1376 function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) {
  1485 function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) {
  1377 	$bookmark = get_bookmark($bookmark);
  1486 	$bookmark = get_bookmark($bookmark);
  1378 
  1487 
  1379 	if ( !current_user_can('manage_links') )
  1488 	if ( !current_user_can('manage_links') )
  1380 		return;
  1489 		return;
  1381 
  1490 
  1382 	if ( empty($link) )
  1491 	if ( empty($link) )
  1383 		$link = __('Edit This');
  1492 		$link = __('Edit This');
  1384 
  1493 
  1385 	$link = '<a href="' . get_edit_bookmark_link( $bookmark ) . '">' . $link . '</a>';
  1494 	$link = '<a href="' . esc_url( get_edit_bookmark_link( $bookmark ) ) . '">' . $link . '</a>';
  1386 
  1495 
  1387 	/**
  1496 	/**
  1388 	 * Filter the bookmark edit link anchor tag.
  1497 	 * Filters the bookmark edit link anchor tag.
  1389 	 *
  1498 	 *
  1390 	 * @since 2.7.0
  1499 	 * @since 2.7.0
  1391 	 *
  1500 	 *
  1392 	 * @param string $link    Anchor tag for the edit link.
  1501 	 * @param string $link    Anchor tag for the edit link.
  1393 	 * @param int    $link_id Bookmark ID.
  1502 	 * @param int    $link_id Bookmark ID.
  1394 	 */
  1503 	 */
  1395 	echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after;
  1504 	echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after;
  1396 }
  1505 }
  1397 
  1506 
  1398 /**
  1507 /**
  1399  * Retrieve edit user link
  1508  * Retrieves the edit user link.
  1400  *
  1509  *
  1401  * @since 3.5.0
  1510  * @since 3.5.0
  1402  *
  1511  *
  1403  * @param int $user_id Optional. User ID. Defaults to the current user.
  1512  * @param int $user_id Optional. User ID. Defaults to the current user.
  1404  * @return string URL to edit user page or empty string.
  1513  * @return string URL to edit user page or empty string.
  1419 		$link = get_edit_profile_url( $user->ID );
  1528 		$link = get_edit_profile_url( $user->ID );
  1420 	else
  1529 	else
  1421 		$link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) );
  1530 		$link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) );
  1422 
  1531 
  1423 	/**
  1532 	/**
  1424 	 * Filter the user edit link.
  1533 	 * Filters the user edit link.
  1425 	 *
  1534 	 *
  1426 	 * @since 3.5.0
  1535 	 * @since 3.5.0
  1427 	 *
  1536 	 *
  1428 	 * @param string $link    The edit link.
  1537 	 * @param string $link    The edit link.
  1429 	 * @param int    $user_id User ID.
  1538 	 * @param int    $user_id User ID.
  1432 }
  1541 }
  1433 
  1542 
  1434 // Navigation links
  1543 // Navigation links
  1435 
  1544 
  1436 /**
  1545 /**
  1437  * Retrieve previous post that is adjacent to current post.
  1546  * Retrieves the previous post that is adjacent to the current post.
  1438  *
  1547  *
  1439  * @since 1.5.0
  1548  * @since 1.5.0
  1440  *
  1549  *
  1441  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term.
  1550  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term. Default false.
  1442  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1551  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1443  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1552  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1444  * @return mixed       Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  1553  * @return null|string|WP_Post Post object if successful. Null if global $post is not set. Empty string if no
       
  1554  *                             corresponding post exists.
  1445  */
  1555  */
  1446 function get_previous_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1556 function get_previous_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1447 	return get_adjacent_post( $in_same_term, $excluded_terms, true, $taxonomy );
  1557 	return get_adjacent_post( $in_same_term, $excluded_terms, true, $taxonomy );
  1448 }
  1558 }
  1449 
  1559 
  1450 /**
  1560 /**
  1451  * Retrieve next post that is adjacent to current post.
  1561  * Retrieves the next post that is adjacent to the current post.
  1452  *
  1562  *
  1453  * @since 1.5.0
  1563  * @since 1.5.0
  1454  *
  1564  *
  1455  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term.
  1565  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term. Default false.
  1456  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1566  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1457  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1567  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1458  * @return mixed       Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  1568  * @return null|string|WP_Post Post object if successful. Null if global $post is not set. Empty string if no
       
  1569  *                             corresponding post exists.
  1459  */
  1570  */
  1460 function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1571 function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1461 	return get_adjacent_post( $in_same_term, $excluded_terms, false, $taxonomy );
  1572 	return get_adjacent_post( $in_same_term, $excluded_terms, false, $taxonomy );
  1462 }
  1573 }
  1463 
  1574 
  1464 /**
  1575 /**
  1465  * Retrieve adjacent post.
  1576  * Retrieves the adjacent post.
  1466  *
  1577  *
  1467  * Can either be next or previous post.
  1578  * Can either be next or previous post.
  1468  *
  1579  *
  1469  * @since 2.5.0
  1580  * @since 2.5.0
  1470  *
  1581  *
  1471  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term.
  1582  * @global wpdb $wpdb WordPress database abstraction object.
  1472  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1583  *
  1473  * @param bool         $previous       Optional. Whether to retrieve previous post.
  1584  * @param bool         $in_same_term   Optional. Whether post should be in a same taxonomy term. Default false.
       
  1585  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
       
  1586  * @param bool         $previous       Optional. Whether to retrieve previous post. Default true
  1474  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1587  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1475  * @return mixed       Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  1588  * @return null|string|WP_Post Post object if successful. Null if global $post is not set. Empty string if no
       
  1589  *                             corresponding post exists.
  1476  */
  1590  */
  1477 function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1591 function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1478 	global $wpdb;
  1592 	global $wpdb;
  1479 
  1593 
  1480 	if ( ( ! $post = get_post() ) || ! taxonomy_exists( $taxonomy ) )
  1594 	if ( ( ! $post = get_post() ) || ! taxonomy_exists( $taxonomy ) )
  1482 
  1596 
  1483 	$current_post_date = $post->post_date;
  1597 	$current_post_date = $post->post_date;
  1484 
  1598 
  1485 	$join = '';
  1599 	$join = '';
  1486 	$where = '';
  1600 	$where = '';
       
  1601 	$adjacent = $previous ? 'previous' : 'next';
  1487 
  1602 
  1488 	if ( $in_same_term || ! empty( $excluded_terms ) ) {
  1603 	if ( $in_same_term || ! empty( $excluded_terms ) ) {
  1489 		$join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
       
  1490 		$where = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
       
  1491 
       
  1492 		if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) {
  1604 		if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) {
  1493 			// back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
  1605 			// back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
  1494 			if ( false !== strpos( $excluded_terms, ' and ' ) ) {
  1606 			if ( false !== strpos( $excluded_terms, ' and ' ) ) {
  1495 				_deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) );
  1607 				_deprecated_argument( __FUNCTION__, '3.3.0', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) );
  1496 				$excluded_terms = explode( ' and ', $excluded_terms );
  1608 				$excluded_terms = explode( ' and ', $excluded_terms );
  1497 			} else {
  1609 			} else {
  1498 				$excluded_terms = explode( ',', $excluded_terms );
  1610 				$excluded_terms = explode( ',', $excluded_terms );
  1499 			}
  1611 			}
  1500 
  1612 
  1501 			$excluded_terms = array_map( 'intval', $excluded_terms );
  1613 			$excluded_terms = array_map( 'intval', $excluded_terms );
  1502 		}
  1614 		}
  1503 
  1615 
  1504 		if ( $in_same_term ) {
  1616 		if ( $in_same_term ) {
       
  1617 			$join .= " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
       
  1618 			$where .= $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
       
  1619 
  1505 			if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
  1620 			if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
  1506 				return '';
  1621 				return '';
  1507 			$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
  1622 			$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
  1508 
  1623 
  1509 			// Remove any exclusions from the term array to include.
  1624 			// Remove any exclusions from the term array to include.
  1514 				return '';
  1629 				return '';
  1515 
  1630 
  1516 			$where .= " AND tt.term_id IN (" . implode( ',', $term_array ) . ")";
  1631 			$where .= " AND tt.term_id IN (" . implode( ',', $term_array ) . ")";
  1517 		}
  1632 		}
  1518 
  1633 
       
  1634 		/**
       
  1635 		 * Filters the IDs of terms excluded from adjacent post queries.
       
  1636 		 *
       
  1637 		 * The dynamic portion of the hook name, `$adjacent`, refers to the type
       
  1638 		 * of adjacency, 'next' or 'previous'.
       
  1639 		 *
       
  1640 		 * @since 4.4.0
       
  1641 		 *
       
  1642 		 * @param string $excluded_terms Array of excluded term IDs.
       
  1643 		 */
       
  1644 		$excluded_terms = apply_filters( "get_{$adjacent}_post_excluded_terms", $excluded_terms );
       
  1645 
  1519 		if ( ! empty( $excluded_terms ) ) {
  1646 		if ( ! empty( $excluded_terms ) ) {
  1520 			$where .= " AND p.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships tr LEFT JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.term_id IN (" . implode( $excluded_terms, ',' ) . ') )';
  1647 			$where .= " AND p.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships tr LEFT JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.term_id IN (" . implode( ',', array_map( 'intval', $excluded_terms ) ) . ') )';
  1521 		}
  1648 		}
  1522 	}
  1649 	}
  1523 
  1650 
  1524 	// 'post_status' clause depends on the current user.
  1651 	// 'post_status' clause depends on the current user.
  1525 	if ( is_user_logged_in() ) {
  1652 	if ( is_user_logged_in() ) {
  1549 		$where .= " )";
  1676 		$where .= " )";
  1550 	} else {
  1677 	} else {
  1551 		$where .= " AND p.post_status = 'publish'";
  1678 		$where .= " AND p.post_status = 'publish'";
  1552 	}
  1679 	}
  1553 
  1680 
  1554 	$adjacent = $previous ? 'previous' : 'next';
       
  1555 	$op = $previous ? '<' : '>';
  1681 	$op = $previous ? '<' : '>';
  1556 	$order = $previous ? 'DESC' : 'ASC';
  1682 	$order = $previous ? 'DESC' : 'ASC';
  1557 
  1683 
  1558 	/**
  1684 	/**
  1559 	 * Filter the JOIN clause in the SQL for an adjacent post query.
  1685 	 * Filters the JOIN clause in the SQL for an adjacent post query.
  1560 	 *
  1686 	 *
  1561 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1687 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1562 	 * of adjacency, 'next' or 'previous'.
  1688 	 * of adjacency, 'next' or 'previous'.
  1563 	 *
  1689 	 *
  1564 	 * @since 2.5.0
  1690 	 * @since 2.5.0
  1565 	 *
  1691 	 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
  1566 	 * @param string $join           The JOIN clause in the SQL.
  1692 	 *
  1567 	 * @param bool   $in_same_term   Whether post should be in a same taxonomy term.
  1693 	 * @param string  $join           The JOIN clause in the SQL.
  1568 	 * @param array  $excluded_terms Array of excluded term IDs.
  1694 	 * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
  1569 	 */
  1695 	 * @param array   $excluded_terms Array of excluded term IDs.
  1570 	$join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms );
  1696 	 * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
  1571 
  1697 	 * @param WP_Post $post           WP_Post object.
  1572 	/**
  1698 	 */
  1573 	 * Filter the WHERE clause in the SQL for an adjacent post query.
  1699 	$join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post );
       
  1700 
       
  1701 	/**
       
  1702 	 * Filters the WHERE clause in the SQL for an adjacent post query.
  1574 	 *
  1703 	 *
  1575 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1704 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1576 	 * of adjacency, 'next' or 'previous'.
  1705 	 * of adjacency, 'next' or 'previous'.
  1577 	 *
  1706 	 *
  1578 	 * @since 2.5.0
  1707 	 * @since 2.5.0
  1579 	 *
  1708 	 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
  1580 	 * @param string $where          The `WHERE` clause in the SQL.
  1709 	 *
  1581 	 * @param bool   $in_same_term   Whether post should be in a same taxonomy term.
  1710 	 * @param string  $where          The `WHERE` clause in the SQL.
  1582 	 * @param array  $excluded_terms Array of excluded term IDs.
  1711 	 * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
  1583 	 */
  1712 	 * @param array   $excluded_terms Array of excluded term IDs.
  1584 	$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms );
  1713 	 * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
  1585 
  1714 	 * @param WP_Post $post           WP_Post object.
  1586 	/**
  1715 	 */
  1587 	 * Filter the ORDER BY clause in the SQL for an adjacent post query.
  1716 	$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post );
       
  1717 
       
  1718 	/**
       
  1719 	 * Filters the ORDER BY clause in the SQL for an adjacent post query.
  1588 	 *
  1720 	 *
  1589 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1721 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1590 	 * of adjacency, 'next' or 'previous'.
  1722 	 * of adjacency, 'next' or 'previous'.
  1591 	 *
  1723 	 *
  1592 	 * @since 2.5.0
  1724 	 * @since 2.5.0
       
  1725 	 * @since 4.4.0 Added the `$post` parameter.
       
  1726 	 * @since 4.9.0 Added the `$order` parameter.
  1593 	 *
  1727 	 *
  1594 	 * @param string $order_by The `ORDER BY` clause in the SQL.
  1728 	 * @param string $order_by The `ORDER BY` clause in the SQL.
  1595 	 */
  1729 	 * @param WP_Post $post    WP_Post object.
  1596 	$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );
  1730 	 * @param string  $order   Sort order. 'DESC' for previous post, 'ASC' for next.
       
  1731 	 */
       
  1732 	$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1", $post, $order );
  1597 
  1733 
  1598 	$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
  1734 	$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
  1599 	$query_key = 'adjacent_post_' . md5( $query );
  1735 	$query_key = 'adjacent_post_' . md5( $query );
  1600 	$result = wp_cache_get( $query_key, 'counts' );
  1736 	$result = wp_cache_get( $query_key, 'counts' );
  1601 	if ( false !== $result ) {
  1737 	if ( false !== $result ) {
  1615 
  1751 
  1616 	return $result;
  1752 	return $result;
  1617 }
  1753 }
  1618 
  1754 
  1619 /**
  1755 /**
  1620  * Get adjacent post relational link.
  1756  * Retrieves the adjacent post relational link.
  1621  *
  1757  *
  1622  * Can either be next or previous post relational link.
  1758  * Can either be next or previous post relational link.
  1623  *
  1759  *
  1624  * @since 2.8.0
  1760  * @since 2.8.0
  1625  *
  1761  *
  1626  * @param string       $title          Optional. Link title format.
  1762  * @param string       $title          Optional. Link title format. Default '%title'.
  1627  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1763  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1628  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1764  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1629  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  1765  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  1630  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1766  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1631  * @return string The adjacent post relational link URL.
  1767  * @return string|void The adjacent post relational link URL.
  1632  */
  1768  */
  1633 function get_adjacent_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1769 function get_adjacent_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1634 	if ( $previous && is_attachment() && $post = get_post() )
  1770 	if ( $previous && is_attachment() && $post = get_post() )
  1635 		$post = get_post( $post->post_parent );
  1771 		$post = get_post( $post->post_parent );
  1636 	else
  1772 	else
  1654 	$link .= "' href='" . get_permalink( $post ) . "' />\n";
  1790 	$link .= "' href='" . get_permalink( $post ) . "' />\n";
  1655 
  1791 
  1656 	$adjacent = $previous ? 'previous' : 'next';
  1792 	$adjacent = $previous ? 'previous' : 'next';
  1657 
  1793 
  1658 	/**
  1794 	/**
  1659 	 * Filter the adjacent post relational link.
  1795 	 * Filters the adjacent post relational link.
  1660 	 *
  1796 	 *
  1661 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1797 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1662 	 * of adjacency, 'next' or 'previous'.
  1798 	 * of adjacency, 'next' or 'previous'.
  1663 	 *
  1799 	 *
  1664 	 * @since 2.8.0
  1800 	 * @since 2.8.0
  1667 	 */
  1803 	 */
  1668 	return apply_filters( "{$adjacent}_post_rel_link", $link );
  1804 	return apply_filters( "{$adjacent}_post_rel_link", $link );
  1669 }
  1805 }
  1670 
  1806 
  1671 /**
  1807 /**
  1672  * Display relational links for the posts adjacent to the current post.
  1808  * Displays the relational links for the posts adjacent to the current post.
  1673  *
  1809  *
  1674  * @since 2.8.0
  1810  * @since 2.8.0
  1675  *
  1811  *
  1676  * @param string       $title          Optional. Link title format.
  1812  * @param string       $title          Optional. Link title format. Default '%title'.
  1677  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1813  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1678  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1814  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1679  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1815  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1680  */
  1816  */
  1681 function adjacent_posts_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1817 function adjacent_posts_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1682 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy );
  1818 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy );
  1683 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy );
  1819 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy );
  1684 }
  1820 }
  1685 
  1821 
  1686 /**
  1822 /**
  1687  * Display relational links for the posts adjacent to the current post for single post pages.
  1823  * Displays relational links for the posts adjacent to the current post for single post pages.
  1688  *
  1824  *
  1689  * This is meant to be attached to actions like 'wp_head'. Do not call this directly in plugins or theme templates.
  1825  * This is meant to be attached to actions like 'wp_head'. Do not call this directly in plugins
       
  1826  * or theme templates.
       
  1827  *
  1690  * @since 3.0.0
  1828  * @since 3.0.0
  1691  *
  1829  *
       
  1830  * @see adjacent_posts_rel_link()
  1692  */
  1831  */
  1693 function adjacent_posts_rel_link_wp_head() {
  1832 function adjacent_posts_rel_link_wp_head() {
  1694 	if ( ! is_single() || is_attachment() ) {
  1833 	if ( ! is_single() || is_attachment() ) {
  1695 		return;
  1834 		return;
  1696 	}
  1835 	}
  1697 	adjacent_posts_rel_link();
  1836 	adjacent_posts_rel_link();
  1698 }
  1837 }
  1699 
  1838 
  1700 /**
  1839 /**
  1701  * Display relational link for the next post adjacent to the current post.
  1840  * Displays the relational link for the next post adjacent to the current post.
  1702  *
  1841  *
  1703  * @since 2.8.0
  1842  * @since 2.8.0
  1704  *
  1843  *
  1705  * @param string       $title          Optional. Link title format.
  1844  * @see get_adjacent_post_rel_link()
  1706  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1845  *
  1707  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1846  * @param string       $title          Optional. Link title format. Default '%title'.
       
  1847  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
       
  1848  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1708  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1849  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1709  */
  1850  */
  1710 function next_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1851 function next_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1711 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy );
  1852 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy );
  1712 }
  1853 }
  1713 
  1854 
  1714 /**
  1855 /**
  1715  * Display relational link for the previous post adjacent to the current post.
  1856  * Displays the relational link for the previous post adjacent to the current post.
  1716  *
  1857  *
  1717  * @since 2.8.0
  1858  * @since 2.8.0
  1718  *
  1859  *
  1719  * @param string       $title          Optional. Link title format.
  1860  * @see get_adjacent_post_rel_link()
  1720  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1861  *
       
  1862  * @param string       $title          Optional. Link title format. Default '%title'.
       
  1863  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1721  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default true.
  1864  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default true.
  1722  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1865  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1723  */
  1866  */
  1724 function prev_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1867 function prev_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1725 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy );
  1868 	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy );
  1726 }
  1869 }
  1727 
  1870 
  1728 /**
  1871 /**
  1729  * Retrieve boundary post.
  1872  * Retrieves the boundary post.
  1730  *
  1873  *
  1731  * Boundary being either the first or last post by publish date within the constraints specified
  1874  * Boundary being either the first or last post by publish date within the constraints specified
  1732  * by $in_same_term or $excluded_terms.
  1875  * by $in_same_term or $excluded_terms.
  1733  *
  1876  *
  1734  * @since 2.8.0
  1877  * @since 2.8.0
  1735  *
  1878  *
  1736  * @param bool         $in_same_term   Optional. Whether returned post should be in a same taxonomy term.
  1879  * @param bool         $in_same_term   Optional. Whether returned post should be in a same taxonomy term.
       
  1880  *                                     Default false.
  1737  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1881  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1738  * @param bool         $start          Optional. Whether to retrieve first or last post.
  1882  *                                     Default empty.
       
  1883  * @param bool         $start          Optional. Whether to retrieve first or last post. Default true
  1739  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1884  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1740  * @return mixed Array containing the boundary post object if successful, null otherwise.
  1885  * @return null|array Array containing the boundary post object if successful, null otherwise.
  1741  */
  1886  */
  1742 function get_boundary_post( $in_same_term = false, $excluded_terms = '', $start = true, $taxonomy = 'category' ) {
  1887 function get_boundary_post( $in_same_term = false, $excluded_terms = '', $start = true, $taxonomy = 'category' ) {
  1743 	$post = get_post();
  1888 	$post = get_post();
  1744 	if ( ! $post || ! is_single() || is_attachment() || ! taxonomy_exists( $taxonomy ) )
  1889 	if ( ! $post || ! is_single() || is_attachment() || ! taxonomy_exists( $taxonomy ) )
  1745 		return null;
  1890 		return null;
  1781 	}
  1926 	}
  1782 
  1927 
  1783 	return get_posts( $query_args );
  1928 	return get_posts( $query_args );
  1784 }
  1929 }
  1785 
  1930 
  1786 /*
  1931 /**
  1787  * Get previous post link that is adjacent to the current post.
  1932  * Retrieves the previous post link that is adjacent to the current post.
  1788  *
  1933  *
  1789  * @since 3.7.0
  1934  * @since 3.7.0
  1790  *
  1935  *
  1791  * @param string       $format         Optional. Link anchor format.
  1936  * @param string       $format         Optional. Link anchor format. Default '&laquo; %link'.
  1792  * @param string       $link           Optional. Link permalink format.
  1937  * @param string       $link           Optional. Link permalink format. Default '%title'.
  1793  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1938  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1794  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1939  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1795  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1940  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1796  * @return string The link URL of the previous post in relation to the current post.
  1941  * @return string The link URL of the previous post in relation to the current post.
  1797  */
  1942  */
  1798 function get_previous_post_link( $format = '&laquo; %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1943 function get_previous_post_link( $format = '&laquo; %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1799 	return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, true, $taxonomy );
  1944 	return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, true, $taxonomy );
  1800 }
  1945 }
  1801 
  1946 
  1802 /**
  1947 /**
  1803  * Display previous post link that is adjacent to the current post.
  1948  * Displays the previous post link that is adjacent to the current post.
  1804  *
  1949  *
  1805  * @since 1.5.0
  1950  * @since 1.5.0
       
  1951  *
  1806  * @see get_previous_post_link()
  1952  * @see get_previous_post_link()
  1807  *
  1953  *
  1808  * @param string       $format         Optional. Link anchor format.
  1954  * @param string       $format         Optional. Link anchor format. Default '&laquo; %link'.
  1809  * @param string       $link           Optional. Link permalink format.
  1955  * @param string       $link           Optional. Link permalink format. Default '%title'.
  1810  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1956  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1811  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1957  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1812  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1958  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1813  */
  1959  */
  1814 function previous_post_link( $format = '&laquo; %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1960 function previous_post_link( $format = '&laquo; %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1815 	echo get_previous_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy );
  1961 	echo get_previous_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy );
  1816 }
  1962 }
  1817 
  1963 
  1818 /**
  1964 /**
  1819  * Get next post link that is adjacent to the current post.
  1965  * Retrieves the next post link that is adjacent to the current post.
  1820  *
  1966  *
  1821  * @since 3.7.0
  1967  * @since 3.7.0
  1822  *
  1968  *
  1823  * @param string       $format         Optional. Link anchor format.
  1969  * @param string       $format         Optional. Link anchor format. Default '&laquo; %link'.
  1824  * @param string       $link           Optional. Link permalink format.
  1970  * @param string       $link           Optional. Link permalink format. Default '%title'.
  1825  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1971  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1826  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1972  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1827  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1973  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1828  * @return string The link URL of the next post in relation to the current post.
  1974  * @return string The link URL of the next post in relation to the current post.
  1829  */
  1975  */
  1830 function get_next_post_link( $format = '%link &raquo;', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1976 function get_next_post_link( $format = '%link &raquo;', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1831 	return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, false, $taxonomy );
  1977 	return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, false, $taxonomy );
  1832 }
  1978 }
  1833 
  1979 
  1834 /**
  1980 /**
  1835  * Display next post link that is adjacent to the current post.
  1981  * Displays the next post link that is adjacent to the current post.
  1836  *
  1982  *
  1837  * @since 1.5.0
  1983  * @since 1.5.0
  1838  * @see get_next_post_link()
  1984  * @see get_next_post_link()
  1839  *
  1985  *
  1840  * @param string       $format         Optional. Link anchor format.
  1986  * @param string       $format         Optional. Link anchor format. Default '&laquo; %link'.
  1841  * @param string       $link           Optional. Link permalink format.
  1987  * @param string       $link           Optional. Link permalink format. Default '%title'
  1842  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  1988  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1843  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  1989  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default empty.
  1844  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1990  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1845  */
  1991  */
  1846 function next_post_link( $format = '%link &raquo;', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1992 function next_post_link( $format = '%link &raquo;', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
  1847 	 echo get_next_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy );
  1993 	 echo get_next_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy );
  1848 }
  1994 }
  1849 
  1995 
  1850 /**
  1996 /**
  1851  * Get adjacent post link.
  1997  * Retrieves the adjacent post link.
  1852  *
  1998  *
  1853  * Can be either next post link or previous.
  1999  * Can be either next post link or previous.
  1854  *
  2000  *
  1855  * @since 3.7.0
  2001  * @since 3.7.0
  1856  *
  2002  *
  1857  * @param string       $format         Link anchor format.
  2003  * @param string       $format         Link anchor format.
  1858  * @param string       $link           Link permalink format.
  2004  * @param string       $link           Link permalink format.
  1859  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  2005  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1860  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded terms IDs.
  2006  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded terms IDs. Default empty.
  1861  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  2007  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  1862  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  2008  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1863  * @return string The link URL of the previous or next post in relation to the current post.
  2009  * @return string The link URL of the previous or next post in relation to the current post.
  1864  */
  2010  */
  1865 function get_adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  2011 function get_adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1891 	}
  2037 	}
  1892 
  2038 
  1893 	$adjacent = $previous ? 'previous' : 'next';
  2039 	$adjacent = $previous ? 'previous' : 'next';
  1894 
  2040 
  1895 	/**
  2041 	/**
  1896 	 * Filter the adjacent post link.
  2042 	 * Filters the adjacent post link.
  1897 	 *
  2043 	 *
  1898 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  2044 	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
  1899 	 * of adjacency, 'next' or 'previous'.
  2045 	 * of adjacency, 'next' or 'previous'.
  1900 	 *
  2046 	 *
  1901 	 * @since 2.6.0
  2047 	 * @since 2.6.0
  1909 	 */
  2055 	 */
  1910 	return apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post, $adjacent );
  2056 	return apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post, $adjacent );
  1911 }
  2057 }
  1912 
  2058 
  1913 /**
  2059 /**
  1914  * Display adjacent post link.
  2060  * Displays the adjacent post link.
  1915  *
  2061  *
  1916  * Can be either next post link or previous.
  2062  * Can be either next post link or previous.
  1917  *
  2063  *
  1918  * @since 2.5.0
  2064  * @since 2.5.0
  1919  *
  2065  *
  1920  * @param string       $format         Link anchor format.
  2066  * @param string       $format         Link anchor format.
  1921  * @param string       $link           Link permalink format.
  2067  * @param string       $link           Link permalink format.
  1922  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term.
  2068  * @param bool         $in_same_term   Optional. Whether link should be in a same taxonomy term. Default false.
  1923  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded category IDs.
  2069  * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded category IDs. Default empty.
  1924  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  2070  * @param bool         $previous       Optional. Whether to display link to previous or next post. Default true.
  1925  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  2071  * @param string       $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
  1926  */
  2072  */
  1927 function adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  2073 function adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  1928 	echo get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, $previous, $taxonomy );
  2074 	echo get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, $previous, $taxonomy );
  1929 }
  2075 }
  1930 
  2076 
  1931 /**
  2077 /**
  1932  * Retrieve links for page numbers.
  2078  * Retrieves the link for a page number.
  1933  *
  2079  *
  1934  * @since 1.5.0
  2080  * @since 1.5.0
  1935  *
  2081  *
  1936  * @param int $pagenum Optional. Page ID.
  2082  * @global WP_Rewrite $wp_rewrite
  1937  * @param bool $escape Optional. Whether to escape the URL for display, with esc_url(). Defaults to true.
  2083  *
  1938 * 	Otherwise, prepares the URL with esc_url_raw().
  2084  * @param int  $pagenum Optional. Page ID. Default 1.
       
  2085  * @param bool $escape  Optional. Whether to escape the URL for display, with esc_url(). Defaults to true.
       
  2086  * 	                    Otherwise, prepares the URL with esc_url_raw().
  1939  * @return string The link URL for the given page number.
  2087  * @return string The link URL for the given page number.
  1940  */
  2088  */
  1941 function get_pagenum_link($pagenum = 1, $escape = true ) {
  2089 function get_pagenum_link($pagenum = 1, $escape = true ) {
  1942 	global $wp_rewrite;
  2090 	global $wp_rewrite;
  1943 
  2091 
  1986 
  2134 
  1987 		$result = $base . $request . $query_string;
  2135 		$result = $base . $request . $query_string;
  1988 	}
  2136 	}
  1989 
  2137 
  1990 	/**
  2138 	/**
  1991 	 * Filter the page number link for the current request.
  2139 	 * Filters the page number link for the current request.
  1992 	 *
  2140 	 *
  1993 	 * @since 2.5.0
  2141 	 * @since 2.5.0
  1994 	 *
  2142 	 *
  1995 	 * @param string $result The page number link.
  2143 	 * @param string $result The page number link.
  1996 	 */
  2144 	 */
  2001 	else
  2149 	else
  2002 		return esc_url_raw( $result );
  2150 		return esc_url_raw( $result );
  2003 }
  2151 }
  2004 
  2152 
  2005 /**
  2153 /**
  2006  * Retrieve next posts page link.
  2154  * Retrieves the next posts page link.
  2007  *
  2155  *
  2008  * Backported from 2.1.3 to 2.0.10.
  2156  * Backported from 2.1.3 to 2.0.10.
  2009  *
  2157  *
  2010  * @since 2.0.10
  2158  * @since 2.0.10
  2011  *
  2159  *
  2012  * @param int $max_page Optional. Max pages.
  2160  * @global int $paged
  2013  * @return string The link URL for next posts page.
  2161  *
       
  2162  * @param int $max_page Optional. Max pages. Default 0.
       
  2163  * @return string|void The link URL for next posts page.
  2014  */
  2164  */
  2015 function get_next_posts_page_link($max_page = 0) {
  2165 function get_next_posts_page_link($max_page = 0) {
  2016 	global $paged;
  2166 	global $paged;
  2017 
  2167 
  2018 	if ( !is_single() ) {
  2168 	if ( !is_single() ) {
  2023 			return get_pagenum_link($nextpage);
  2173 			return get_pagenum_link($nextpage);
  2024 	}
  2174 	}
  2025 }
  2175 }
  2026 
  2176 
  2027 /**
  2177 /**
  2028  * Display or return the next posts page link.
  2178  * Displays or retrieves the next posts page link.
  2029  *
  2179  *
  2030  * @since 0.71
  2180  * @since 0.71
  2031  *
  2181  *
  2032  * @param int $max_page Optional. Max pages.
  2182  * @param int   $max_page Optional. Max pages. Default 0.
  2033  * @param boolean $echo Optional. Echo or return;
  2183  * @param bool  $echo     Optional. Whether to echo the link. Default true.
  2034  * @return string The link URL for next posts page if `$echo = false`.
  2184  * @return string|void The link URL for next posts page if `$echo = false`.
  2035  */
  2185  */
  2036 function next_posts( $max_page = 0, $echo = true ) {
  2186 function next_posts( $max_page = 0, $echo = true ) {
  2037 	$output = esc_url( get_next_posts_page_link( $max_page ) );
  2187 	$output = esc_url( get_next_posts_page_link( $max_page ) );
  2038 
  2188 
  2039 	if ( $echo )
  2189 	if ( $echo )
  2041 	else
  2191 	else
  2042 		return $output;
  2192 		return $output;
  2043 }
  2193 }
  2044 
  2194 
  2045 /**
  2195 /**
  2046  * Return the next posts page link.
  2196  * Retrieves the next posts page link.
  2047  *
  2197  *
  2048  * @since 2.7.0
  2198  * @since 2.7.0
  2049  *
  2199  *
  2050  * @param string $label Content for link text.
  2200  * @global int      $paged
  2051  * @param int $max_page Optional. Max pages.
  2201  * @global WP_Query $wp_query
  2052  * @return string|null HTML-formatted next posts page link.
  2202  *
       
  2203  * @param string $label    Content for link text.
       
  2204  * @param int    $max_page Optional. Max pages. Default 0.
       
  2205  * @return string|void HTML-formatted next posts page link.
  2053  */
  2206  */
  2054 function get_next_posts_link( $label = null, $max_page = 0 ) {
  2207 function get_next_posts_link( $label = null, $max_page = 0 ) {
  2055 	global $paged, $wp_query;
  2208 	global $paged, $wp_query;
  2056 
  2209 
  2057 	if ( !$max_page )
  2210 	if ( !$max_page )
  2065 	if ( null === $label )
  2218 	if ( null === $label )
  2066 		$label = __( 'Next Page &raquo;' );
  2219 		$label = __( 'Next Page &raquo;' );
  2067 
  2220 
  2068 	if ( !is_single() && ( $nextpage <= $max_page ) ) {
  2221 	if ( !is_single() && ( $nextpage <= $max_page ) ) {
  2069 		/**
  2222 		/**
  2070 		 * Filter the anchor tag attributes for the next posts page link.
  2223 		 * Filters the anchor tag attributes for the next posts page link.
  2071 		 *
  2224 		 *
  2072 		 * @since 2.7.0
  2225 		 * @since 2.7.0
  2073 		 *
  2226 		 *
  2074 		 * @param string $attributes Attributes for the anchor tag.
  2227 		 * @param string $attributes Attributes for the anchor tag.
  2075 		 */
  2228 		 */
  2078 		return '<a href="' . next_posts( $max_page, false ) . "\" $attr>" . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) . '</a>';
  2231 		return '<a href="' . next_posts( $max_page, false ) . "\" $attr>" . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) . '</a>';
  2079 	}
  2232 	}
  2080 }
  2233 }
  2081 
  2234 
  2082 /**
  2235 /**
  2083  * Display the next posts page link.
  2236  * Displays the next posts page link.
  2084  *
  2237  *
  2085  * @since 0.71
  2238  * @since 0.71
  2086  *
  2239  *
  2087  * @param string $label Content for link text.
  2240  * @param string $label    Content for link text.
  2088  * @param int $max_page Optional. Max pages.
  2241  * @param int    $max_page Optional. Max pages. Default 0.
  2089  */
  2242  */
  2090 function next_posts_link( $label = null, $max_page = 0 ) {
  2243 function next_posts_link( $label = null, $max_page = 0 ) {
  2091 	echo get_next_posts_link( $label, $max_page );
  2244 	echo get_next_posts_link( $label, $max_page );
  2092 }
  2245 }
  2093 
  2246 
  2094 /**
  2247 /**
  2095  * Retrieve previous posts page link.
  2248  * Retrieves the previous posts page link.
  2096  *
  2249  *
  2097  * Will only return string, if not on a single page or post.
  2250  * Will only return string, if not on a single page or post.
  2098  *
  2251  *
  2099  * Backported to 2.0.10 from 2.1.3.
  2252  * Backported to 2.0.10 from 2.1.3.
  2100  *
  2253  *
  2101  * @since 2.0.10
  2254  * @since 2.0.10
  2102  *
  2255  *
  2103  * @return string|null The link for the previous posts page.
  2256  * @global int $paged
       
  2257  *
       
  2258  * @return string|void The link for the previous posts page.
  2104  */
  2259  */
  2105 function get_previous_posts_page_link() {
  2260 function get_previous_posts_page_link() {
  2106 	global $paged;
  2261 	global $paged;
  2107 
  2262 
  2108 	if ( !is_single() ) {
  2263 	if ( !is_single() ) {
  2112 		return get_pagenum_link($nextpage);
  2267 		return get_pagenum_link($nextpage);
  2113 	}
  2268 	}
  2114 }
  2269 }
  2115 
  2270 
  2116 /**
  2271 /**
  2117  * Display or return the previous posts page link.
  2272  * Displays or retrieves the previous posts page link.
  2118  *
  2273  *
  2119  * @since 0.71
  2274  * @since 0.71
  2120  *
  2275  *
  2121  * @param boolean $echo Optional. Echo or return;
  2276  * @param bool $echo Optional. Whether to echo the link. Default true.
  2122  * @return string The previous posts page link if `$echo = false`.
  2277  * @return string|void The previous posts page link if `$echo = false`.
  2123  */
  2278  */
  2124 function previous_posts( $echo = true ) {
  2279 function previous_posts( $echo = true ) {
  2125 	$output = esc_url( get_previous_posts_page_link() );
  2280 	$output = esc_url( get_previous_posts_page_link() );
  2126 
  2281 
  2127 	if ( $echo )
  2282 	if ( $echo )
  2129 	else
  2284 	else
  2130 		return $output;
  2285 		return $output;
  2131 }
  2286 }
  2132 
  2287 
  2133 /**
  2288 /**
  2134  * Return the previous posts page link.
  2289  * Retrieves the previous posts page link.
  2135  *
  2290  *
  2136  * @since 2.7.0
  2291  * @since 2.7.0
  2137  *
  2292  *
       
  2293  * @global int $paged
       
  2294  *
  2138  * @param string $label Optional. Previous page link text.
  2295  * @param string $label Optional. Previous page link text.
  2139  * @return string|null HTML-formatted previous page link.
  2296  * @return string|void HTML-formatted previous page link.
  2140  */
  2297  */
  2141 function get_previous_posts_link( $label = null ) {
  2298 function get_previous_posts_link( $label = null ) {
  2142 	global $paged;
  2299 	global $paged;
  2143 
  2300 
  2144 	if ( null === $label )
  2301 	if ( null === $label )
  2145 		$label = __( '&laquo; Previous Page' );
  2302 		$label = __( '&laquo; Previous Page' );
  2146 
  2303 
  2147 	if ( !is_single() && $paged > 1 ) {
  2304 	if ( !is_single() && $paged > 1 ) {
  2148 		/**
  2305 		/**
  2149 		 * Filter the anchor tag attributes for the previous posts page link.
  2306 		 * Filters the anchor tag attributes for the previous posts page link.
  2150 		 *
  2307 		 *
  2151 		 * @since 2.7.0
  2308 		 * @since 2.7.0
  2152 		 *
  2309 		 *
  2153 		 * @param string $attributes Attributes for the anchor tag.
  2310 		 * @param string $attributes Attributes for the anchor tag.
  2154 		 */
  2311 		 */
  2156 		return '<a href="' . previous_posts( false ) . "\" $attr>". preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label ) .'</a>';
  2313 		return '<a href="' . previous_posts( false ) . "\" $attr>". preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label ) .'</a>';
  2157 	}
  2314 	}
  2158 }
  2315 }
  2159 
  2316 
  2160 /**
  2317 /**
  2161  * Display the previous posts page link.
  2318  * Displays the previous posts page link.
  2162  *
  2319  *
  2163  * @since 0.71
  2320  * @since 0.71
  2164  *
  2321  *
  2165  * @param string $label Optional. Previous page link text.
  2322  * @param string $label Optional. Previous page link text.
  2166  */
  2323  */
  2167 function previous_posts_link( $label = null ) {
  2324 function previous_posts_link( $label = null ) {
  2168 	echo get_previous_posts_link( $label );
  2325 	echo get_previous_posts_link( $label );
  2169 }
  2326 }
  2170 
  2327 
  2171 /**
  2328 /**
  2172  * Return post pages link navigation for previous and next pages.
  2329  * Retrieves the post pages link navigation for previous and next pages.
  2173  *
  2330  *
  2174  * @since 2.8.0
  2331  * @since 2.8.0
  2175  *
  2332  *
  2176  * @param string|array $args Optional args.
  2333  * @global WP_Query $wp_query
       
  2334  *
       
  2335  * @param string|array $args {
       
  2336  *     Optional. Arguments to build the post pages link navigation.
       
  2337  *
       
  2338  *     @type string $sep      Separator character. Default '&#8212;'.
       
  2339  *     @type string $prelabel Link text to display for the previous page link.
       
  2340  *                            Default '&laquo; Previous Page'.
       
  2341  *     @type string $nxtlabel Link text to display for the next page link.
       
  2342  *                            Default 'Next Page &raquo;'.
       
  2343  * }
  2177  * @return string The posts link navigation.
  2344  * @return string The posts link navigation.
  2178  */
  2345  */
  2179 function get_posts_nav_link( $args = array() ) {
  2346 function get_posts_nav_link( $args = array() ) {
  2180 	global $wp_query;
  2347 	global $wp_query;
  2181 
  2348 
  2206 	return $return;
  2373 	return $return;
  2207 
  2374 
  2208 }
  2375 }
  2209 
  2376 
  2210 /**
  2377 /**
  2211  * Display post pages link navigation for previous and next pages.
  2378  * Displays the post pages link navigation for previous and next pages.
  2212  *
  2379  *
  2213  * @since 0.71
  2380  * @since 0.71
  2214  *
  2381  *
  2215  * @param string $sep Optional. Separator for posts navigation links.
  2382  * @param string $sep      Optional. Separator for posts navigation links. Default empty.
  2216  * @param string $prelabel Optional. Label for previous pages.
  2383  * @param string $prelabel Optional. Label for previous pages. Default empty.
  2217  * @param string $nxtlabel Optional Label for next pages.
  2384  * @param string $nxtlabel Optional Label for next pages. Default empty.
  2218  */
  2385  */
  2219 function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) {
  2386 function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) {
  2220 	$args = array_filter( compact('sep', 'prelabel', 'nxtlabel') );
  2387 	$args = array_filter( compact('sep', 'prelabel', 'nxtlabel') );
  2221 	echo get_posts_nav_link($args);
  2388 	echo get_posts_nav_link($args);
  2222 }
  2389 }
  2223 
  2390 
  2224 /**
  2391 /**
  2225  * Return navigation to next/previous post when applicable.
  2392  * Retrieves the navigation to next/previous post, when applicable.
  2226  *
  2393  *
  2227  * @since 4.1.0
  2394  * @since 4.1.0
       
  2395  * @since 4.4.0 Introduced the `in_same_term`, `excluded_terms`, and `taxonomy` arguments.
  2228  *
  2396  *
  2229  * @param array $args {
  2397  * @param array $args {
  2230  *     Optional. Default post navigation arguments. Default empty array.
  2398  *     Optional. Default post navigation arguments. Default empty array.
  2231  *
  2399  *
  2232  *     @type string $prev_text          Anchor text to display in the previous post link. Default `%title`.
  2400  *     @type string       $prev_text          Anchor text to display in the previous post link. Default '%title'.
  2233  *     @type string $next_text          Anchor text to display in the next post link. Default `%title`.
  2401  *     @type string       $next_text          Anchor text to display in the next post link. Default '%title'.
  2234  *     @type string $screen_reader_text Screen reader text for nav element. Default 'Post navigation'.
  2402  *     @type bool         $in_same_term       Whether link should be in a same taxonomy term. Default false.
       
  2403  *     @type array|string $excluded_terms     Array or comma-separated list of excluded term IDs. Default empty.
       
  2404  *     @type string       $taxonomy           Taxonomy, if `$in_same_term` is true. Default 'category'.
       
  2405  *     @type string       $screen_reader_text Screen reader text for nav element. Default 'Post navigation'.
  2235  * }
  2406  * }
  2236  * @return string Markup for post links.
  2407  * @return string Markup for post links.
  2237  */
  2408  */
  2238 function get_the_post_navigation( $args = array() ) {
  2409 function get_the_post_navigation( $args = array() ) {
  2239 	$args = wp_parse_args( $args, array(
  2410 	$args = wp_parse_args( $args, array(
  2240 		'prev_text'          => '%title',
  2411 		'prev_text'          => '%title',
  2241 		'next_text'          => '%title',
  2412 		'next_text'          => '%title',
       
  2413 		'in_same_term'       => false,
       
  2414 		'excluded_terms'     => '',
       
  2415 		'taxonomy'           => 'category',
  2242 		'screen_reader_text' => __( 'Post navigation' ),
  2416 		'screen_reader_text' => __( 'Post navigation' ),
  2243 	) );
  2417 	) );
  2244 
  2418 
  2245 	$navigation = '';
  2419 	$navigation = '';
  2246 	$previous   = get_previous_post_link( '<div class="nav-previous">%link</div>', $args['prev_text'] );
  2420 
  2247 	$next       = get_next_post_link( '<div class="nav-next">%link</div>', $args['next_text'] );
  2421 	$previous = get_previous_post_link(
       
  2422 		'<div class="nav-previous">%link</div>',
       
  2423 		$args['prev_text'],
       
  2424 		$args['in_same_term'],
       
  2425 		$args['excluded_terms'],
       
  2426 		$args['taxonomy']
       
  2427 	);
       
  2428 
       
  2429 	$next = get_next_post_link(
       
  2430 		'<div class="nav-next">%link</div>',
       
  2431 		$args['next_text'],
       
  2432 		$args['in_same_term'],
       
  2433 		$args['excluded_terms'],
       
  2434 		$args['taxonomy']
       
  2435 	);
  2248 
  2436 
  2249 	// Only add markup if there's somewhere to navigate to.
  2437 	// Only add markup if there's somewhere to navigate to.
  2250 	if ( $previous || $next ) {
  2438 	if ( $previous || $next ) {
  2251 		$navigation = _navigation_markup( $previous . $next, 'post-navigation', $args['screen_reader_text'] );
  2439 		$navigation = _navigation_markup( $previous . $next, 'post-navigation', $args['screen_reader_text'] );
  2252 	}
  2440 	}
  2253 
  2441 
  2254 	return $navigation;
  2442 	return $navigation;
  2255 }
  2443 }
  2256 
  2444 
  2257 /**
  2445 /**
  2258  * Display navigation to next/previous post when applicable.
  2446  * Displays the navigation to next/previous post, when applicable.
  2259  *
  2447  *
  2260  * @since 4.1.0
  2448  * @since 4.1.0
  2261  *
  2449  *
  2262  * @param array $args Optional. See {@see get_the_post_navigation()} for available
  2450  * @param array $args Optional. See get_the_post_navigation() for available arguments.
  2263  *                    arguments. Default empty array.
  2451  *                    Default empty array.
  2264  */
  2452  */
  2265 function the_post_navigation( $args = array() ) {
  2453 function the_post_navigation( $args = array() ) {
  2266 	echo get_the_post_navigation( $args );
  2454 	echo get_the_post_navigation( $args );
  2267 }
  2455 }
  2268 
  2456 
  2269 /**
  2457 /**
  2270  * Return navigation to next/previous set of posts when applicable.
  2458  * Returns the navigation to next/previous set of posts, when applicable.
  2271  *
  2459  *
  2272  * @since 4.1.0
  2460  * @since 4.1.0
  2273  *
  2461  *
  2274  * @global WP_Query $wp_query WordPress Query object.
  2462  * @global WP_Query $wp_query WordPress Query object.
  2275  *
  2463  *
  2312 
  2500 
  2313 	return $navigation;
  2501 	return $navigation;
  2314 }
  2502 }
  2315 
  2503 
  2316 /**
  2504 /**
  2317  * Display navigation to next/previous set of posts when applicable.
  2505  * Displays the navigation to next/previous set of posts, when applicable.
  2318  *
  2506  *
  2319  * @since 4.1.0
  2507  * @since 4.1.0
  2320  *
  2508  *
  2321  * @param array $args Optional. See {@see get_the_posts_navigation()} for available
  2509  * @param array $args Optional. See get_the_posts_navigation() for available arguments.
  2322  *                    arguments. Default empty array.
  2510  *                    Default empty array.
  2323  */
  2511  */
  2324 function the_posts_navigation( $args = array() ) {
  2512 function the_posts_navigation( $args = array() ) {
  2325 	echo get_the_posts_navigation( $args );
  2513 	echo get_the_posts_navigation( $args );
  2326 }
  2514 }
  2327 
  2515 
  2328 /**
  2516 /**
  2329  * Return a paginated navigation to next/previous set of posts,
  2517  * Retrieves a paginated navigation to next/previous set of posts, when applicable.
  2330  * when applicable.
       
  2331  *
  2518  *
  2332  * @since 4.1.0
  2519  * @since 4.1.0
  2333  *
  2520  *
  2334  * @param array $args {
  2521  * @param array $args {
  2335  *     Optional. Default pagination arguments, {@see paginate_links()}.
  2522  *     Optional. Default pagination arguments, see paginate_links().
  2336  *
  2523  *
  2337  *     @type string $screen_reader_text Screen reader text for navigation element.
  2524  *     @type string $screen_reader_text Screen reader text for navigation element.
  2338  *                                      Default 'Posts navigation'.
  2525  *                                      Default 'Posts navigation'.
  2339  * }
  2526  * }
  2340  * @return string Markup for pagination links.
  2527  * @return string Markup for pagination links.
  2344 
  2531 
  2345 	// Don't print empty markup if there's only one page.
  2532 	// Don't print empty markup if there's only one page.
  2346 	if ( $GLOBALS['wp_query']->max_num_pages > 1 ) {
  2533 	if ( $GLOBALS['wp_query']->max_num_pages > 1 ) {
  2347 		$args = wp_parse_args( $args, array(
  2534 		$args = wp_parse_args( $args, array(
  2348 			'mid_size'           => 1,
  2535 			'mid_size'           => 1,
  2349 			'prev_text'          => _x( 'Previous', 'previous post' ),
  2536 			'prev_text'          => _x( 'Previous', 'previous set of posts' ),
  2350 			'next_text'          => _x( 'Next', 'next post' ),
  2537 			'next_text'          => _x( 'Next', 'next set of posts' ),
  2351 			'screen_reader_text' => __( 'Posts navigation' ),
  2538 			'screen_reader_text' => __( 'Posts navigation' ),
  2352 		) );
  2539 		) );
  2353 
  2540 
  2354 		// Make sure we get a string back. Plain is the next best thing.
  2541 		// Make sure we get a string back. Plain is the next best thing.
  2355 		if ( isset( $args['type'] ) && 'array' == $args['type'] ) {
  2542 		if ( isset( $args['type'] ) && 'array' == $args['type'] ) {
  2366 
  2553 
  2367 	return $navigation;
  2554 	return $navigation;
  2368 }
  2555 }
  2369 
  2556 
  2370 /**
  2557 /**
  2371  * Display a paginated navigation to next/previous set of posts,
  2558  * Displays a paginated navigation to next/previous set of posts, when applicable.
  2372  * when applicable.
       
  2373  *
  2559  *
  2374  * @since 4.1.0
  2560  * @since 4.1.0
  2375  *
  2561  *
  2376  * @param array $args Optional. See {@see get_the_posts_pagination()} for available arguments.
  2562  * @param array $args Optional. See get_the_posts_pagination() for available arguments.
  2377  *                    Default empty array.
  2563  *                    Default empty array.
  2378  */
  2564  */
  2379 function the_posts_pagination( $args = array() ) {
  2565 function the_posts_pagination( $args = array() ) {
  2380 	echo get_the_posts_pagination( $args );
  2566 	echo get_the_posts_pagination( $args );
  2381 }
  2567 }
  2400 	<nav class="navigation %1$s" role="navigation">
  2586 	<nav class="navigation %1$s" role="navigation">
  2401 		<h2 class="screen-reader-text">%2$s</h2>
  2587 		<h2 class="screen-reader-text">%2$s</h2>
  2402 		<div class="nav-links">%3$s</div>
  2588 		<div class="nav-links">%3$s</div>
  2403 	</nav>';
  2589 	</nav>';
  2404 
  2590 
       
  2591 	/**
       
  2592 	 * Filters the navigation markup template.
       
  2593 	 *
       
  2594 	 * Note: The filtered template HTML must contain specifiers for the navigation
       
  2595 	 * class (%1$s), the screen-reader-text value (%2$s), and placement of the
       
  2596 	 * navigation links (%3$s):
       
  2597 	 *
       
  2598 	 *     <nav class="navigation %1$s" role="navigation">
       
  2599 	 *         <h2 class="screen-reader-text">%2$s</h2>
       
  2600 	 *         <div class="nav-links">%3$s</div>
       
  2601 	 *     </nav>
       
  2602 	 *
       
  2603 	 * @since 4.4.0
       
  2604 	 *
       
  2605 	 * @param string $template The default template.
       
  2606 	 * @param string $class    The class passed by the calling function.
       
  2607 	 * @return string Navigation template.
       
  2608 	 */
       
  2609 	$template = apply_filters( 'navigation_markup_template', $template, $class );
       
  2610 
  2405 	return sprintf( $template, sanitize_html_class( $class ), esc_html( $screen_reader_text ), $links );
  2611 	return sprintf( $template, sanitize_html_class( $class ), esc_html( $screen_reader_text ), $links );
  2406 }
  2612 }
  2407 
  2613 
  2408 /**
  2614 /**
  2409  * Retrieve comments page number link.
  2615  * Retrieves the comments page number link.
  2410  *
  2616  *
  2411  * @since 2.7.0
  2617  * @since 2.7.0
  2412  *
  2618  *
  2413  * @param int $pagenum Optional. Page number.
  2619  * @global WP_Rewrite $wp_rewrite
  2414  * @param int $max_page Optional. The maximum number of comment pages.
  2620  *
       
  2621  * @param int $pagenum  Optional. Page number. Default 1.
       
  2622  * @param int $max_page Optional. The maximum number of comment pages. Default 0.
  2415  * @return string The comments page number link URL.
  2623  * @return string The comments page number link URL.
  2416  */
  2624  */
  2417 function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) {
  2625 function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) {
  2418 	global $wp_rewrite;
  2626 	global $wp_rewrite;
  2419 
  2627 
  2436 	}
  2644 	}
  2437 
  2645 
  2438 	$result .= '#comments';
  2646 	$result .= '#comments';
  2439 
  2647 
  2440 	/**
  2648 	/**
  2441 	 * Filter the comments page number link for the current request.
  2649 	 * Filters the comments page number link for the current request.
  2442 	 *
  2650 	 *
  2443 	 * @since 2.7.0
  2651 	 * @since 2.7.0
  2444 	 *
  2652 	 *
  2445 	 * @param string $result The comments page number link.
  2653 	 * @param string $result The comments page number link.
  2446 	 */
  2654 	 */
  2447 	$result = apply_filters( 'get_comments_pagenum_link', $result );
  2655 	return apply_filters( 'get_comments_pagenum_link', $result );
  2448 
  2656 }
  2449 	return $result;
  2657 
  2450 }
  2658 /**
  2451 
  2659  * Retrieves the link to the next comments page.
  2452 /**
       
  2453  * Return the link to next comments page.
       
  2454  *
  2660  *
  2455  * @since 2.7.1
  2661  * @since 2.7.1
  2456  *
  2662  *
  2457  * @param string $label Optional. Label for link text.
  2663  * @global WP_Query $wp_query
  2458  * @param int $max_page Optional. Max page.
  2664  *
  2459  * @return string|null HTML-formatted link for the next page of comments.
  2665  * @param string $label    Optional. Label for link text. Default empty.
       
  2666  * @param int    $max_page Optional. Max page. Default 0.
       
  2667  * @return string|void HTML-formatted link for the next page of comments.
  2460  */
  2668  */
  2461 function get_next_comments_link( $label = '', $max_page = 0 ) {
  2669 function get_next_comments_link( $label = '', $max_page = 0 ) {
  2462 	global $wp_query;
  2670 	global $wp_query;
  2463 
  2671 
  2464 	if ( !is_singular() || !get_option('page_comments') )
  2672 	if ( ! is_singular() )
  2465 		return;
  2673 		return;
  2466 
  2674 
  2467 	$page = get_query_var('cpage');
  2675 	$page = get_query_var('cpage');
  2468 
  2676 
  2469 	if ( ! $page ) {
  2677 	if ( ! $page ) {
  2483 
  2691 
  2484 	if ( empty($label) )
  2692 	if ( empty($label) )
  2485 		$label = __('Newer Comments &raquo;');
  2693 		$label = __('Newer Comments &raquo;');
  2486 
  2694 
  2487 	/**
  2695 	/**
  2488 	 * Filter the anchor tag attributes for the next comments page link.
  2696 	 * Filters the anchor tag attributes for the next comments page link.
  2489 	 *
  2697 	 *
  2490 	 * @since 2.7.0
  2698 	 * @since 2.7.0
  2491 	 *
  2699 	 *
  2492 	 * @param string $attributes Attributes for the anchor tag.
  2700 	 * @param string $attributes Attributes for the anchor tag.
  2493 	 */
  2701 	 */
  2494 	return '<a href="' . esc_url( get_comments_pagenum_link( $nextpage, $max_page ) ) . '" ' . apply_filters( 'next_comments_link_attributes', '' ) . '>'. preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) .'</a>';
  2702 	return '<a href="' . esc_url( get_comments_pagenum_link( $nextpage, $max_page ) ) . '" ' . apply_filters( 'next_comments_link_attributes', '' ) . '>'. preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) .'</a>';
  2495 }
  2703 }
  2496 
  2704 
  2497 /**
  2705 /**
  2498  * Display the link to next comments page.
  2706  * Displays the link to the next comments page.
  2499  *
  2707  *
  2500  * @since 2.7.0
  2708  * @since 2.7.0
  2501  *
  2709  *
  2502  * @param string $label Optional. Label for link text.
  2710  * @param string $label    Optional. Label for link text. Default empty.
  2503  * @param int $max_page Optional. Max page.
  2711  * @param int    $max_page Optional. Max page. Default 0.
  2504  */
  2712  */
  2505 function next_comments_link( $label = '', $max_page = 0 ) {
  2713 function next_comments_link( $label = '', $max_page = 0 ) {
  2506 	echo get_next_comments_link( $label, $max_page );
  2714 	echo get_next_comments_link( $label, $max_page );
  2507 }
  2715 }
  2508 
  2716 
  2509 /**
  2717 /**
  2510  * Return the previous comments page link.
  2718  * Retrieves the link to the previous comments page.
  2511  *
  2719  *
  2512  * @since 2.7.1
  2720  * @since 2.7.1
  2513  *
  2721  *
  2514  * @param string $label Optional. Label for comments link text.
  2722  * @param string $label Optional. Label for comments link text. Default empty.
  2515  * @return string|null HTML-formatted link for the previous page of comments.
  2723  * @return string|void HTML-formatted link for the previous page of comments.
  2516  */
  2724  */
  2517 function get_previous_comments_link( $label = '' ) {
  2725 function get_previous_comments_link( $label = '' ) {
  2518 	if ( !is_singular() || !get_option('page_comments') )
  2726 	if ( ! is_singular() )
  2519 		return;
  2727 		return;
  2520 
  2728 
  2521 	$page = get_query_var('cpage');
  2729 	$page = get_query_var('cpage');
  2522 
  2730 
  2523 	if ( intval($page) <= 1 )
  2731 	if ( intval($page) <= 1 )
  2527 
  2735 
  2528 	if ( empty($label) )
  2736 	if ( empty($label) )
  2529 		$label = __('&laquo; Older Comments');
  2737 		$label = __('&laquo; Older Comments');
  2530 
  2738 
  2531 	/**
  2739 	/**
  2532 	 * Filter the anchor tag attributes for the previous comments page link.
  2740 	 * Filters the anchor tag attributes for the previous comments page link.
  2533 	 *
  2741 	 *
  2534 	 * @since 2.7.0
  2742 	 * @since 2.7.0
  2535 	 *
  2743 	 *
  2536 	 * @param string $attributes Attributes for the anchor tag.
  2744 	 * @param string $attributes Attributes for the anchor tag.
  2537 	 */
  2745 	 */
  2538 	return '<a href="' . esc_url( get_comments_pagenum_link( $prevpage ) ) . '" ' . apply_filters( 'previous_comments_link_attributes', '' ) . '>' . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) .'</a>';
  2746 	return '<a href="' . esc_url( get_comments_pagenum_link( $prevpage ) ) . '" ' . apply_filters( 'previous_comments_link_attributes', '' ) . '>' . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) .'</a>';
  2539 }
  2747 }
  2540 
  2748 
  2541 /**
  2749 /**
  2542  * Display the previous comments page link.
  2750  * Displays the link to the previous comments page.
  2543  *
  2751  *
  2544  * @since 2.7.0
  2752  * @since 2.7.0
  2545  *
  2753  *
  2546  * @param string $label Optional. Label for comments link text.
  2754  * @param string $label Optional. Label for comments link text. Default empty.
  2547  */
  2755  */
  2548 function previous_comments_link( $label = '' ) {
  2756 function previous_comments_link( $label = '' ) {
  2549 	echo get_previous_comments_link( $label );
  2757 	echo get_previous_comments_link( $label );
  2550 }
  2758 }
  2551 
  2759 
  2552 /**
  2760 /**
  2553  * Create pagination links for the comments on the current post.
  2761  * Displays or retrieves pagination links for the comments on the current post.
  2554  *
  2762  *
  2555  * @see paginate_links()
  2763  * @see paginate_links()
  2556  * @since 2.7.0
  2764  * @since 2.7.0
  2557  *
  2765  *
  2558  * @param string|array $args Optional args. See paginate_links().
  2766  * @global WP_Rewrite $wp_rewrite
  2559  * @return string Markup for pagination links.
  2767  *
  2560 */
  2768  * @param string|array $args Optional args. See paginate_links(). Default empty array.
  2561 function paginate_comments_links($args = array()) {
  2769  * @return string|void Markup for pagination links.
       
  2770  */
       
  2771 function paginate_comments_links( $args = array() ) {
  2562 	global $wp_rewrite;
  2772 	global $wp_rewrite;
  2563 
  2773 
  2564 	if ( !is_singular() || !get_option('page_comments') )
  2774 	if ( ! is_singular() )
  2565 		return;
  2775 		return;
  2566 
  2776 
  2567 	$page = get_query_var('cpage');
  2777 	$page = get_query_var('cpage');
  2568 	if ( !$page )
  2778 	if ( !$page )
  2569 		$page = 1;
  2779 		$page = 1;
  2587 	else
  2797 	else
  2588 		return $page_links;
  2798 		return $page_links;
  2589 }
  2799 }
  2590 
  2800 
  2591 /**
  2801 /**
  2592  * Retrieve the Press This bookmarklet link.
  2802  * Retrieves navigation to next/previous set of comments, when applicable.
  2593  *
  2803  *
  2594  * Use this in 'a' element 'href' attribute.
  2804  * @since 4.4.0
  2595  *
  2805  *
  2596  * @since 2.6.0
  2806  * @param array $args {
  2597  *
  2807  *     Optional. Default comments navigation arguments.
  2598  * @return string The Press This bookmarklet link URL.
  2808  *
  2599  */
  2809  *     @type string $prev_text          Anchor text to display in the previous comments link.
  2600 function get_shortcut_link() {
  2810  *                                      Default 'Older comments'.
  2601 	global $is_IE, $wp_version;
  2811  *     @type string $next_text          Anchor text to display in the next comments link.
  2602 
  2812  *                                      Default 'Newer comments'.
  2603 	include_once( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
  2813  *     @type string $screen_reader_text Screen reader text for nav element. Default 'Comments navigation'.
  2604 	$bookmarklet_version = $GLOBALS['wp_press_this']->version;
  2814  * }
  2605 	$link = '';
  2815  * @return string Markup for comments links.
  2606 
  2816  */
  2607 	if ( $is_IE ) {
  2817 function get_the_comments_navigation( $args = array() ) {
  2608 		/**
  2818 	$navigation = '';
  2609 		 * Return the old/shorter bookmarklet code for MSIE 8 and lower,
  2819 
  2610 		 * since they only support a max length of ~2000 characters for
  2820 	// Are there comments to navigate through?
  2611 		 * bookmark[let] URLs, which is way to small for our smarter one.
  2821 	if ( get_comment_pages_count() > 1 ) {
  2612 		 * Do update the version number so users do not get the "upgrade your
  2822 		$args = wp_parse_args( $args, array(
  2613 		 * bookmarklet" notice when using PT in those browsers.
  2823 			'prev_text'          => __( 'Older comments' ),
  2614 		 */
  2824 			'next_text'          => __( 'Newer comments' ),
  2615 		$ua = $_SERVER['HTTP_USER_AGENT'];
  2825 			'screen_reader_text' => __( 'Comments navigation' ),
  2616 
  2826 		) );
  2617 		if ( ! empty( $ua ) && preg_match( '/\bMSIE (\d)/', $ua, $matches ) && (int) $matches[1] <= 8 ) {
  2827 
  2618 			$url = wp_json_encode( admin_url( 'press-this.php' ) );
  2828 		$prev_link = get_previous_comments_link( $args['prev_text'] );
  2619 
  2829 		$next_link = get_next_comments_link( $args['next_text'] );
  2620 			$link = 'javascript:var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,' .
  2830 
  2621 				's=(e?e():(k)?k():(x?x.createRange().text:0)),f=' . $url . ',l=d.location,e=encodeURIComponent,' .
  2831 		if ( $prev_link ) {
  2622 				'u=f+"?u="+e(l.href)+"&t="+e(d.title)+"&s="+e(s)+"&v=' . $bookmarklet_version . '";' .
  2832 			$navigation .= '<div class="nav-previous">' . $prev_link . '</div>';
  2623 				'a=function(){if(!w.open(u,"t","toolbar=0,resizable=1,scrollbars=1,status=1,width=600,height=700"))l.href=u;};' .
       
  2624 				'if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else a();void(0)';
       
  2625 		}
  2833 		}
  2626 	}
  2834 
  2627 
  2835 		if ( $next_link ) {
  2628 	if ( empty( $link ) ) {
  2836 			$navigation .= '<div class="nav-next">' . $next_link . '</div>';
  2629 		$src = @file_get_contents( ABSPATH . 'wp-admin/js/bookmarklet.min.js' );
       
  2630 
       
  2631 		if ( $src ) {
       
  2632 			$url = wp_json_encode( admin_url( 'press-this.php' ) . '?v=' . $bookmarklet_version );
       
  2633 			$link = 'javascript:' . str_replace( 'window.pt_url', $url, $src );
       
  2634 		}
  2837 		}
  2635 	}
  2838 
  2636 
  2839 		$navigation = _navigation_markup( $navigation, 'comment-navigation', $args['screen_reader_text'] );
  2637 	$link = str_replace( array( "\r", "\n", "\t" ),  '', $link );
  2840 	}
  2638 
  2841 
  2639 	/**
  2842 	return $navigation;
  2640 	 * Filter the Press This bookmarklet link.
  2843 }
  2641 	 *
  2844 
  2642 	 * @since 2.6.0
  2845 /**
  2643 	 *
  2846  * Displays navigation to next/previous set of comments, when applicable.
  2644 	 * @param string $link The Press This bookmarklet link.
  2847  *
  2645 	 */
  2848  * @since 4.4.0
  2646 	return apply_filters( 'shortcut_link', $link );
  2849  *
  2647 }
  2850  * @param array $args See get_the_comments_navigation() for available arguments. Default empty array.
  2648 
  2851  */
  2649 /**
  2852 function the_comments_navigation( $args = array() ) {
  2650  * Retrieve the home url for the current site.
  2853 	echo get_the_comments_navigation( $args );
  2651  *
  2854 }
  2652  * Returns the 'home' option with the appropriate protocol, 'https' if
  2855 
  2653  * {@see is_ssl()} and 'http' otherwise. If `$scheme` is 'http' or 'https',
  2856 /**
  2654  * `is_ssl()` is overridden.
  2857  * Retrieves a paginated navigation to next/previous set of comments, when applicable.
       
  2858  *
       
  2859  * @since 4.4.0
       
  2860  *
       
  2861  * @see paginate_comments_links()
       
  2862  *
       
  2863  * @param array $args {
       
  2864  *     Optional. Default pagination arguments.
       
  2865  *
       
  2866  *     @type string $screen_reader_text Screen reader text for nav element. Default 'Comments navigation'.
       
  2867  * }
       
  2868  * @return string Markup for pagination links.
       
  2869  */
       
  2870 function get_the_comments_pagination( $args = array() ) {
       
  2871 	$navigation = '';
       
  2872 	$args       = wp_parse_args( $args, array(
       
  2873 		'screen_reader_text' => __( 'Comments navigation' ),
       
  2874 	) );
       
  2875 	$args['echo'] = false;
       
  2876 
       
  2877 	// Make sure we get a string back. Plain is the next best thing.
       
  2878 	if ( isset( $args['type'] ) && 'array' == $args['type'] ) {
       
  2879 		$args['type'] = 'plain';
       
  2880 	}
       
  2881 
       
  2882 	$links = paginate_comments_links( $args );
       
  2883 
       
  2884 	if ( $links ) {
       
  2885 		$navigation = _navigation_markup( $links, 'comments-pagination', $args['screen_reader_text'] );
       
  2886 	}
       
  2887 
       
  2888 	return $navigation;
       
  2889 }
       
  2890 
       
  2891 /**
       
  2892  * Displays a paginated navigation to next/previous set of comments, when applicable.
       
  2893  *
       
  2894  * @since 4.4.0
       
  2895  *
       
  2896  * @param array $args See get_the_comments_pagination() for available arguments. Default empty array.
       
  2897  */
       
  2898 function the_comments_pagination( $args = array() ) {
       
  2899 	echo get_the_comments_pagination( $args );
       
  2900 }
       
  2901 
       
  2902 /**
       
  2903  * Retrieves the URL for the current site where the front end is accessible.
       
  2904  *
       
  2905  * Returns the 'home' option with the appropriate protocol. The protocol will be 'https'
       
  2906  * if is_ssl() evaluates to true; otherwise, it will be the same as the 'home' option.
       
  2907  * If `$scheme` is 'http' or 'https', is_ssl() is overridden.
  2655  *
  2908  *
  2656  * @since 3.0.0
  2909  * @since 3.0.0
  2657  *
  2910  *
  2658  * @param  string $path   Optional. Path relative to the home url. Default empty.
  2911  * @param  string      $path   Optional. Path relative to the home URL. Default empty.
  2659  * @param  string $scheme Optional. Scheme to give the home url context. Accepts
  2912  * @param  string|null $scheme Optional. Scheme to give the home URL context. Accepts
  2660  *                        'http', 'https', or 'relative'. Default null.
  2913  *                             'http', 'https', 'relative', 'rest', or null. Default null.
  2661  * @return string Home url link with optional path appended.
  2914  * @return string Home URL link with optional path appended.
  2662 */
  2915  */
  2663 function home_url( $path = '', $scheme = null ) {
  2916 function home_url( $path = '', $scheme = null ) {
  2664 	return get_home_url( null, $path, $scheme );
  2917 	return get_home_url( null, $path, $scheme );
  2665 }
  2918 }
  2666 
  2919 
  2667 /**
  2920 /**
  2668  * Retrieve the home url for a given site.
  2921  * Retrieves the URL for a given site where the front end is accessible.
  2669  *
  2922  *
  2670  * Returns the 'home' option with the appropriate protocol, 'https' if
  2923  * Returns the 'home' option with the appropriate protocol. The protocol will be 'https'
  2671  * {@see is_ssl()} and 'http' otherwise. If `$scheme` is 'http' or 'https',
  2924  * if is_ssl() evaluates to true; otherwise, it will be the same as the 'home' option.
  2672  * `is_ssl()` is
  2925  * If `$scheme` is 'http' or 'https', is_ssl() is overridden.
  2673  * overridden.
       
  2674  *
  2926  *
  2675  * @since 3.0.0
  2927  * @since 3.0.0
  2676  *
  2928  *
  2677  * @param  int         $blog_id     Optional. Blog ID. Default null (current blog).
  2929  * @global string $pagenow
  2678  * @param  string      $path        Optional. Path relative to the home URL. Default empty.
  2930  *
  2679  * @param  string|null $orig_scheme Optional. Scheme to give the home URL context. Accepts
  2931  * @param  int         $blog_id Optional. Site ID. Default null (current site).
  2680  *                                  'http', 'https', 'relative', or null. Default null.
  2932  * @param  string      $path    Optional. Path relative to the home URL. Default empty.
       
  2933  * @param  string|null $scheme  Optional. Scheme to give the home URL context. Accepts
       
  2934  *                              'http', 'https', 'relative', 'rest', or null. Default null.
  2681  * @return string Home URL link with optional path appended.
  2935  * @return string Home URL link with optional path appended.
  2682 */
  2936  */
  2683 function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
  2937 function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
       
  2938 	global $pagenow;
       
  2939 
  2684 	$orig_scheme = $scheme;
  2940 	$orig_scheme = $scheme;
  2685 
  2941 
  2686 	if ( empty( $blog_id ) || !is_multisite() ) {
  2942 	if ( empty( $blog_id ) || !is_multisite() ) {
  2687 		$url = get_option( 'home' );
  2943 		$url = get_option( 'home' );
  2688 	} else {
  2944 	} else {
  2690 		$url = get_option( 'home' );
  2946 		$url = get_option( 'home' );
  2691 		restore_current_blog();
  2947 		restore_current_blog();
  2692 	}
  2948 	}
  2693 
  2949 
  2694 	if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
  2950 	if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
  2695 		if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $GLOBALS['pagenow'] )
  2951 		if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $pagenow )
  2696 			$scheme = 'https';
  2952 			$scheme = 'https';
  2697 		else
  2953 		else
  2698 			$scheme = parse_url( $url, PHP_URL_SCHEME );
  2954 			$scheme = parse_url( $url, PHP_URL_SCHEME );
  2699 	}
  2955 	}
  2700 
  2956 
  2702 
  2958 
  2703 	if ( $path && is_string( $path ) )
  2959 	if ( $path && is_string( $path ) )
  2704 		$url .= '/' . ltrim( $path, '/' );
  2960 		$url .= '/' . ltrim( $path, '/' );
  2705 
  2961 
  2706 	/**
  2962 	/**
  2707 	 * Filter the home URL.
  2963 	 * Filters the home URL.
  2708 	 *
  2964 	 *
  2709 	 * @since 3.0.0
  2965 	 * @since 3.0.0
  2710 	 *
  2966 	 *
  2711 	 * @param string      $url         The complete home URL including scheme and path.
  2967 	 * @param string      $url         The complete home URL including scheme and path.
  2712 	 * @param string      $path        Path relative to the home URL. Blank string if no path is specified.
  2968 	 * @param string      $path        Path relative to the home URL. Blank string if no path is specified.
  2713 	 * @param string|null $orig_scheme Scheme to give the home URL context. Accepts 'http', 'https', 'relative' or null.
  2969 	 * @param string|null $orig_scheme Scheme to give the home URL context. Accepts 'http', 'https',
  2714 	 * @param int|null    $blog_id     Blog ID, or null for the current blog.
  2970 	 *                                 'relative', 'rest', or null.
       
  2971 	 * @param int|null    $blog_id     Site ID, or null for the current site.
  2715 	 */
  2972 	 */
  2716 	return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );
  2973 	return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );
  2717 }
  2974 }
  2718 
  2975 
  2719 /**
  2976 /**
  2720  * Retrieve the site url for the current site.
  2977  * Retrieves the URL for the current site where WordPress application files
       
  2978  * (e.g. wp-blog-header.php or the wp-admin/ folder) are accessible.
  2721  *
  2979  *
  2722  * Returns the 'site_url' option with the appropriate protocol, 'https' if
  2980  * Returns the 'site_url' option with the appropriate protocol, 'https' if
  2723  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
  2981  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
  2724  * overridden.
  2982  * overridden.
  2725  *
  2983  *
  2726  * @since 3.0.0
  2984  * @since 3.0.0
  2727  *
  2985  *
  2728  * @param string $path Optional. Path relative to the site url.
  2986  * @param string $path   Optional. Path relative to the site URL. Default empty.
  2729  * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme().
  2987  * @param string $scheme Optional. Scheme to give the site URL context. See set_url_scheme().
  2730  * @return string Site url link with optional path appended.
  2988  * @return string Site URL link with optional path appended.
  2731 */
  2989  */
  2732 function site_url( $path = '', $scheme = null ) {
  2990 function site_url( $path = '', $scheme = null ) {
  2733 	return get_site_url( null, $path, $scheme );
  2991 	return get_site_url( null, $path, $scheme );
  2734 }
  2992 }
  2735 
  2993 
  2736 /**
  2994 /**
  2737  * Retrieve the site url for a given site.
  2995  * Retrieves the URL for a given site where WordPress application files
       
  2996  * (e.g. wp-blog-header.php or the wp-admin/ folder) are accessible.
  2738  *
  2997  *
  2739  * Returns the 'site_url' option with the appropriate protocol, 'https' if
  2998  * Returns the 'site_url' option with the appropriate protocol, 'https' if
  2740  * {@see is_ssl()} and 'http' otherwise. If `$scheme` is 'http' or 'https',
  2999  * is_ssl() and 'http' otherwise. If `$scheme` is 'http' or 'https',
  2741  * `is_ssl()` is overridden.
  3000  * `is_ssl()` is overridden.
  2742  *
  3001  *
  2743  * @since 3.0.0
  3002  * @since 3.0.0
  2744  *
  3003  *
  2745  * @param int    $blog_id Optional. Blog ID. Default null (current site).
  3004  * @param int    $blog_id Optional. Site ID. Default null (current site).
  2746  * @param string $path    Optional. Path relative to the site url. Default empty.
  3005  * @param string $path    Optional. Path relative to the site URL. Default empty.
  2747  * @param string $scheme  Optional. Scheme to give the site url context. Accepts
  3006  * @param string $scheme  Optional. Scheme to give the site URL context. Accepts
  2748  *                        'http', 'https', 'login', 'login_post', 'admin', or
  3007  *                        'http', 'https', 'login', 'login_post', 'admin', or
  2749  *                        'relative'. Default null.
  3008  *                        'relative'. Default null.
  2750  * @return string Site url link with optional path appended.
  3009  * @return string Site URL link with optional path appended.
  2751 */
  3010  */
  2752 function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
  3011 function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
  2753 	if ( empty( $blog_id ) || !is_multisite() ) {
  3012 	if ( empty( $blog_id ) || !is_multisite() ) {
  2754 		$url = get_option( 'siteurl' );
  3013 		$url = get_option( 'siteurl' );
  2755 	} else {
  3014 	} else {
  2756 		switch_to_blog( $blog_id );
  3015 		switch_to_blog( $blog_id );
  2762 
  3021 
  2763 	if ( $path && is_string( $path ) )
  3022 	if ( $path && is_string( $path ) )
  2764 		$url .= '/' . ltrim( $path, '/' );
  3023 		$url .= '/' . ltrim( $path, '/' );
  2765 
  3024 
  2766 	/**
  3025 	/**
  2767 	 * Filter the site URL.
  3026 	 * Filters the site URL.
  2768 	 *
  3027 	 *
  2769 	 * @since 2.7.0
  3028 	 * @since 2.7.0
  2770 	 *
  3029 	 *
  2771 	 * @param string      $url     The complete site URL including scheme and path.
  3030 	 * @param string      $url     The complete site URL including scheme and path.
  2772 	 * @param string      $path    Path relative to the site URL. Blank string if no path is specified.
  3031 	 * @param string      $path    Path relative to the site URL. Blank string if no path is specified.
  2773 	 * @param string|null $scheme  Scheme to give the site URL context. Accepts 'http', 'https', 'login',
  3032 	 * @param string|null $scheme  Scheme to give the site URL context. Accepts 'http', 'https', 'login',
  2774 	 *                             'login_post', 'admin', 'relative' or null.
  3033 	 *                             'login_post', 'admin', 'relative' or null.
  2775 	 * @param int|null    $blog_id Blog ID, or null for the current blog.
  3034 	 * @param int|null    $blog_id Site ID, or null for the current site.
  2776 	 */
  3035 	 */
  2777 	return apply_filters( 'site_url', $url, $path, $scheme, $blog_id );
  3036 	return apply_filters( 'site_url', $url, $path, $scheme, $blog_id );
  2778 }
  3037 }
  2779 
  3038 
  2780 /**
  3039 /**
  2781  * Retrieve the url to the admin area for the current site.
  3040  * Retrieves the URL to the admin area for the current site.
  2782  *
  3041  *
  2783  * @since 2.6.0
  3042  * @since 2.6.0
  2784  *
  3043  *
  2785  * @param string $path Optional path relative to the admin url.
  3044  * @param string $path   Optional path relative to the admin URL.
  2786  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3045  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl().
  2787  * @return string Admin url link with optional path appended.
  3046  *                       'http' or 'https' can be passed to force those schemes.
  2788 */
  3047  * @return string Admin URL link with optional path appended.
       
  3048  */
  2789 function admin_url( $path = '', $scheme = 'admin' ) {
  3049 function admin_url( $path = '', $scheme = 'admin' ) {
  2790 	return get_admin_url( null, $path, $scheme );
  3050 	return get_admin_url( null, $path, $scheme );
  2791 }
  3051 }
  2792 
  3052 
  2793 /**
  3053 /**
  2794  * Retrieves the url to the admin area for a given site.
  3054  * Retrieves the URL to the admin area for a given site.
  2795  *
  3055  *
  2796  * @since 3.0.0
  3056  * @since 3.0.0
  2797  *
  3057  *
  2798  * @param int    $blog_id Optional. Blog ID. Default null (current site).
  3058  * @param int    $blog_id Optional. Site ID. Default null (current site).
  2799  * @param string $path    Optional. Path relative to the admin url. Default empty.
  3059  * @param string $path    Optional. Path relative to the admin URL. Default empty.
  2800  * @param string $scheme  Optional. The scheme to use. Accepts 'http' or 'https',
  3060  * @param string $scheme  Optional. The scheme to use. Accepts 'http' or 'https',
  2801  *                        to force those schemes. Default 'admin', which obeys
  3061  *                        to force those schemes. Default 'admin', which obeys
  2802  *                        {@see force_ssl_admin()} and {@see is_ssl()}.
  3062  *                        force_ssl_admin() and is_ssl().
  2803  * @return string Admin url link with optional path appended.
  3063  * @return string Admin URL link with optional path appended.
  2804 */
  3064  */
  2805 function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) {
  3065 function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) {
  2806 	$url = get_site_url($blog_id, 'wp-admin/', $scheme);
  3066 	$url = get_site_url($blog_id, 'wp-admin/', $scheme);
  2807 
  3067 
  2808 	if ( $path && is_string( $path ) )
  3068 	if ( $path && is_string( $path ) )
  2809 		$url .= ltrim( $path, '/' );
  3069 		$url .= ltrim( $path, '/' );
  2810 
  3070 
  2811 	/**
  3071 	/**
  2812 	 * Filter the admin area URL.
  3072 	 * Filters the admin area URL.
  2813 	 *
  3073 	 *
  2814 	 * @since 2.8.0
  3074 	 * @since 2.8.0
  2815 	 *
  3075 	 *
  2816 	 * @param string   $url     The complete admin area URL including scheme and path.
  3076 	 * @param string   $url     The complete admin area URL including scheme and path.
  2817 	 * @param string   $path    Path relative to the admin area URL. Blank string if no path is specified.
  3077 	 * @param string   $path    Path relative to the admin area URL. Blank string if no path is specified.
  2818 	 * @param int|null $blog_id Blog ID, or null for the current blog.
  3078 	 * @param int|null $blog_id Site ID, or null for the current site.
  2819 	 */
  3079 	 */
  2820 	return apply_filters( 'admin_url', $url, $path, $blog_id );
  3080 	return apply_filters( 'admin_url', $url, $path, $blog_id );
  2821 }
  3081 }
  2822 
  3082 
  2823 /**
  3083 /**
  2824  * Retrieve the url to the includes directory.
  3084  * Retrieves the URL to the includes directory.
  2825  *
  3085  *
  2826  * @since 2.6.0
  3086  * @since 2.6.0
  2827  *
  3087  *
  2828  * @param string $path Optional. Path relative to the includes url.
  3088  * @param string $path   Optional. Path relative to the includes URL. Default empty.
  2829  * @param string $scheme Optional. Scheme to give the includes url context.
  3089  * @param string $scheme Optional. Scheme to give the includes URL context. Accepts
  2830  * @return string Includes url link with optional path appended.
  3090  *                       'http', 'https', or 'relative'. Default null.
  2831 */
  3091  * @return string Includes URL link with optional path appended.
       
  3092  */
  2832 function includes_url( $path = '', $scheme = null ) {
  3093 function includes_url( $path = '', $scheme = null ) {
  2833 	$url = site_url( '/' . WPINC . '/', $scheme );
  3094 	$url = site_url( '/' . WPINC . '/', $scheme );
  2834 
  3095 
  2835 	if ( $path && is_string( $path ) )
  3096 	if ( $path && is_string( $path ) )
  2836 		$url .= ltrim($path, '/');
  3097 		$url .= ltrim($path, '/');
  2837 
  3098 
  2838 	/**
  3099 	/**
  2839 	 * Filter the URL to the includes directory.
  3100 	 * Filters the URL to the includes directory.
  2840 	 *
  3101 	 *
  2841 	 * @since 2.8.0
  3102 	 * @since 2.8.0
  2842 	 *
  3103 	 *
  2843 	 * @param string $url  The complete URL to the includes directory including scheme and path.
  3104 	 * @param string $url  The complete URL to the includes directory including scheme and path.
  2844 	 * @param string $path Path relative to the URL to the wp-includes directory. Blank string
  3105 	 * @param string $path Path relative to the URL to the wp-includes directory. Blank string
  2846 	 */
  3107 	 */
  2847 	return apply_filters( 'includes_url', $url, $path );
  3108 	return apply_filters( 'includes_url', $url, $path );
  2848 }
  3109 }
  2849 
  3110 
  2850 /**
  3111 /**
  2851  * Retrieve the url to the content directory.
  3112  * Retrieves the URL to the content directory.
  2852  *
  3113  *
  2853  * @since 2.6.0
  3114  * @since 2.6.0
  2854  *
  3115  *
  2855  * @param string $path Optional. Path relative to the content url.
  3116  * @param string $path Optional. Path relative to the content URL. Default empty.
  2856  * @return string Content url link with optional path appended.
  3117  * @return string Content URL link with optional path appended.
  2857 */
  3118  */
  2858 function content_url($path = '') {
  3119 function content_url( $path = '' ) {
  2859 	$url = set_url_scheme( WP_CONTENT_URL );
  3120 	$url = set_url_scheme( WP_CONTENT_URL );
  2860 
  3121 
  2861 	if ( $path && is_string( $path ) )
  3122 	if ( $path && is_string( $path ) )
  2862 		$url .= '/' . ltrim($path, '/');
  3123 		$url .= '/' . ltrim($path, '/');
  2863 
  3124 
  2864 	/**
  3125 	/**
  2865 	 * Filter the URL to the content directory.
  3126 	 * Filters the URL to the content directory.
  2866 	 *
  3127 	 *
  2867 	 * @since 2.8.0
  3128 	 * @since 2.8.0
  2868 	 *
  3129 	 *
  2869 	 * @param string $url  The complete URL to the content directory including scheme and path.
  3130 	 * @param string $url  The complete URL to the content directory including scheme and path.
  2870 	 * @param string $path Path relative to the URL to the content directory. Blank string
  3131 	 * @param string $path Path relative to the URL to the content directory. Blank string
  2872 	 */
  3133 	 */
  2873 	return apply_filters( 'content_url', $url, $path);
  3134 	return apply_filters( 'content_url', $url, $path);
  2874 }
  3135 }
  2875 
  3136 
  2876 /**
  3137 /**
  2877  * Retrieve a URL within the plugins or mu-plugins directory.
  3138  * Retrieves a URL within the plugins or mu-plugins directory.
  2878  *
  3139  *
  2879  * Defaults to the plugins directory URL if no arguments are supplied.
  3140  * Defaults to the plugins directory URL if no arguments are supplied.
  2880  *
  3141  *
  2881  * @since 2.6.0
  3142  * @since 2.6.0
  2882  *
  3143  *
  2884  *                        the relative directory if $plugin is supplied. Default empty.
  3145  *                        the relative directory if $plugin is supplied. Default empty.
  2885  * @param  string $plugin Optional. A full path to a file inside a plugin or mu-plugin.
  3146  * @param  string $plugin Optional. A full path to a file inside a plugin or mu-plugin.
  2886  *                        The URL will be relative to its directory. Default empty.
  3147  *                        The URL will be relative to its directory. Default empty.
  2887  *                        Typically this is done by passing `__FILE__` as the argument.
  3148  *                        Typically this is done by passing `__FILE__` as the argument.
  2888  * @return string Plugins URL link with optional paths appended.
  3149  * @return string Plugins URL link with optional paths appended.
  2889 */
  3150  */
  2890 function plugins_url( $path = '', $plugin = '' ) {
  3151 function plugins_url( $path = '', $plugin = '' ) {
  2891 
  3152 
  2892 	$path = wp_normalize_path( $path );
  3153 	$path = wp_normalize_path( $path );
  2893 	$plugin = wp_normalize_path( $plugin );
  3154 	$plugin = wp_normalize_path( $plugin );
  2894 	$mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR );
  3155 	$mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR );
  2909 
  3170 
  2910 	if ( $path && is_string( $path ) )
  3171 	if ( $path && is_string( $path ) )
  2911 		$url .= '/' . ltrim($path, '/');
  3172 		$url .= '/' . ltrim($path, '/');
  2912 
  3173 
  2913 	/**
  3174 	/**
  2914 	 * Filter the URL to the plugins directory.
  3175 	 * Filters the URL to the plugins directory.
  2915 	 *
  3176 	 *
  2916 	 * @since 2.8.0
  3177 	 * @since 2.8.0
  2917 	 *
  3178 	 *
  2918 	 * @param string $url    The complete URL to the plugins directory including scheme and path.
  3179 	 * @param string $url    The complete URL to the plugins directory including scheme and path.
  2919 	 * @param string $path   Path relative to the URL to the plugins directory. Blank string
  3180 	 * @param string $path   Path relative to the URL to the plugins directory. Blank string
  2923 	 */
  3184 	 */
  2924 	return apply_filters( 'plugins_url', $url, $path, $plugin );
  3185 	return apply_filters( 'plugins_url', $url, $path, $plugin );
  2925 }
  3186 }
  2926 
  3187 
  2927 /**
  3188 /**
  2928  * Retrieve the site url for the current network.
  3189  * Retrieves the site URL for the current network.
  2929  *
  3190  *
  2930  * Returns the site url with the appropriate protocol, 'https' if
  3191  * Returns the site URL with the appropriate protocol, 'https' if
  2931  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
  3192  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
  2932  * overridden.
  3193  * overridden.
  2933  *
  3194  *
  2934  * @since 3.0.0
  3195  * @since 3.0.0
  2935  *
  3196  *
  2936  * @param string $path Optional. Path relative to the site url.
  3197  * @see set_url_scheme()
  2937  * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme().
  3198  *
  2938  * @return string Site url link with optional path appended.
  3199  * @param string $path   Optional. Path relative to the site URL. Default empty.
  2939 */
  3200  * @param string $scheme Optional. Scheme to give the site URL context. Accepts
       
  3201  *                       'http', 'https', or 'relative'. Default null.
       
  3202  * @return string Site URL link with optional path appended.
       
  3203  */
  2940 function network_site_url( $path = '', $scheme = null ) {
  3204 function network_site_url( $path = '', $scheme = null ) {
  2941 	if ( ! is_multisite() )
  3205 	if ( ! is_multisite() )
  2942 		return site_url($path, $scheme);
  3206 		return site_url($path, $scheme);
  2943 
  3207 
  2944 	$current_site = get_current_site();
  3208 	$current_network = get_network();
  2945 
  3209 
  2946 	if ( 'relative' == $scheme )
  3210 	if ( 'relative' == $scheme )
  2947 		$url = $current_site->path;
  3211 		$url = $current_network->path;
  2948 	else
  3212 	else
  2949 		$url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme );
  3213 		$url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $scheme );
  2950 
  3214 
  2951 	if ( $path && is_string( $path ) )
  3215 	if ( $path && is_string( $path ) )
  2952 		$url .= ltrim( $path, '/' );
  3216 		$url .= ltrim( $path, '/' );
  2953 
  3217 
  2954 	/**
  3218 	/**
  2955 	 * Filter the network site URL.
  3219 	 * Filters the network site URL.
  2956 	 *
  3220 	 *
  2957 	 * @since 3.0.0
  3221 	 * @since 3.0.0
  2958 	 *
  3222 	 *
  2959 	 * @param string      $url    The complete network site URL including scheme and path.
  3223 	 * @param string      $url    The complete network site URL including scheme and path.
  2960 	 * @param string      $path   Path relative to the network site URL. Blank string if
  3224 	 * @param string      $path   Path relative to the network site URL. Blank string if
  2964 	 */
  3228 	 */
  2965 	return apply_filters( 'network_site_url', $url, $path, $scheme );
  3229 	return apply_filters( 'network_site_url', $url, $path, $scheme );
  2966 }
  3230 }
  2967 
  3231 
  2968 /**
  3232 /**
  2969  * Retrieves the home url for the current network.
  3233  * Retrieves the home URL for the current network.
  2970  *
  3234  *
  2971  * Returns the home url with the appropriate protocol, 'https' {@see is_ssl()}
  3235  * Returns the home URL with the appropriate protocol, 'https' is_ssl()
  2972  * and 'http' otherwise. If `$scheme` is 'http' or 'https', `is_ssl()` is
  3236  * and 'http' otherwise. If `$scheme` is 'http' or 'https', `is_ssl()` is
  2973  * overridden.
  3237  * overridden.
  2974  *
  3238  *
  2975  * @since 3.0.0
  3239  * @since 3.0.0
  2976  *
  3240  *
  2977  * @param  string $path   Optional. Path relative to the home url. Default empty.
  3241  * @param  string $path   Optional. Path relative to the home URL. Default empty.
  2978  * @param  string $scheme Optional. Scheme to give the home url context. Accepts
  3242  * @param  string $scheme Optional. Scheme to give the home URL context. Accepts
  2979  *                        'http', 'https', or 'relative'. Default null.
  3243  *                        'http', 'https', or 'relative'. Default null.
  2980  * @return string Home url link with optional path appended.
  3244  * @return string Home URL link with optional path appended.
  2981 */
  3245  */
  2982 function network_home_url( $path = '', $scheme = null ) {
  3246 function network_home_url( $path = '', $scheme = null ) {
  2983 	if ( ! is_multisite() )
  3247 	if ( ! is_multisite() )
  2984 		return home_url($path, $scheme);
  3248 		return home_url($path, $scheme);
  2985 
  3249 
  2986 	$current_site = get_current_site();
  3250 	$current_network = get_network();
  2987 	$orig_scheme = $scheme;
  3251 	$orig_scheme = $scheme;
  2988 
  3252 
  2989 	if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) )
  3253 	if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) )
  2990 		$scheme = is_ssl() && ! is_admin() ? 'https' : 'http';
  3254 		$scheme = is_ssl() && ! is_admin() ? 'https' : 'http';
  2991 
  3255 
  2992 	if ( 'relative' == $scheme )
  3256 	if ( 'relative' == $scheme )
  2993 		$url = $current_site->path;
  3257 		$url = $current_network->path;
  2994 	else
  3258 	else
  2995 		$url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme );
  3259 		$url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $scheme );
  2996 
  3260 
  2997 	if ( $path && is_string( $path ) )
  3261 	if ( $path && is_string( $path ) )
  2998 		$url .= ltrim( $path, '/' );
  3262 		$url .= ltrim( $path, '/' );
  2999 
  3263 
  3000 	/**
  3264 	/**
  3001 	 * Filter the network home URL.
  3265 	 * Filters the network home URL.
  3002 	 *
  3266 	 *
  3003 	 * @since 3.0.0
  3267 	 * @since 3.0.0
  3004 	 *
  3268 	 *
  3005 	 * @param string      $url         The complete network home URL including scheme and path.
  3269 	 * @param string      $url         The complete network home URL including scheme and path.
  3006 	 * @param string      $path        Path relative to the network home URL. Blank string
  3270 	 * @param string      $path        Path relative to the network home URL. Blank string
  3010 	 */
  3274 	 */
  3011 	return apply_filters( 'network_home_url', $url, $path, $orig_scheme);
  3275 	return apply_filters( 'network_home_url', $url, $path, $orig_scheme);
  3012 }
  3276 }
  3013 
  3277 
  3014 /**
  3278 /**
  3015  * Retrieve the url to the admin area for the network.
  3279  * Retrieves the URL to the admin area for the network.
  3016  *
  3280  *
  3017  * @since 3.0.0
  3281  * @since 3.0.0
  3018  *
  3282  *
  3019  * @param string $path Optional path relative to the admin url.
  3283  * @param string $path   Optional path relative to the admin URL. Default empty.
  3020  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3284  * @param string $scheme Optional. The scheme to use. Default is 'admin', which obeys force_ssl_admin()
  3021  * @return string Admin url link with optional path appended.
  3285  *                       and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3022 */
  3286  * @return string Admin URL link with optional path appended.
       
  3287  */
  3023 function network_admin_url( $path = '', $scheme = 'admin' ) {
  3288 function network_admin_url( $path = '', $scheme = 'admin' ) {
  3024 	if ( ! is_multisite() )
  3289 	if ( ! is_multisite() )
  3025 		return admin_url( $path, $scheme );
  3290 		return admin_url( $path, $scheme );
  3026 
  3291 
  3027 	$url = network_site_url('wp-admin/network/', $scheme);
  3292 	$url = network_site_url('wp-admin/network/', $scheme);
  3028 
  3293 
  3029 	if ( $path && is_string( $path ) )
  3294 	if ( $path && is_string( $path ) )
  3030 		$url .= ltrim($path, '/');
  3295 		$url .= ltrim($path, '/');
  3031 
  3296 
  3032 	/**
  3297 	/**
  3033 	 * Filter the network admin URL.
  3298 	 * Filters the network admin URL.
  3034 	 *
  3299 	 *
  3035 	 * @since 3.0.0
  3300 	 * @since 3.0.0
  3036 	 *
  3301 	 *
  3037 	 * @param string $url  The complete network admin URL including scheme and path.
  3302 	 * @param string $url  The complete network admin URL including scheme and path.
  3038 	 * @param string $path Path relative to the network admin URL. Blank string if
  3303 	 * @param string $path Path relative to the network admin URL. Blank string if
  3040 	 */
  3305 	 */
  3041 	return apply_filters( 'network_admin_url', $url, $path );
  3306 	return apply_filters( 'network_admin_url', $url, $path );
  3042 }
  3307 }
  3043 
  3308 
  3044 /**
  3309 /**
  3045  * Retrieve the url to the admin area for the current user.
  3310  * Retrieves the URL to the admin area for the current user.
  3046  *
  3311  *
  3047  * @since 3.0.0
  3312  * @since 3.0.0
  3048  *
  3313  *
  3049  * @param string $path Optional path relative to the admin url.
  3314  * @param string $path   Optional. Path relative to the admin URL. Default empty.
  3050  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3315  * @param string $scheme Optional. The scheme to use. Default is 'admin', which obeys force_ssl_admin()
  3051  * @return string Admin url link with optional path appended.
  3316  *                       and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3052 */
  3317  * @return string Admin URL link with optional path appended.
       
  3318  */
  3053 function user_admin_url( $path = '', $scheme = 'admin' ) {
  3319 function user_admin_url( $path = '', $scheme = 'admin' ) {
  3054 	$url = network_site_url('wp-admin/user/', $scheme);
  3320 	$url = network_site_url('wp-admin/user/', $scheme);
  3055 
  3321 
  3056 	if ( $path && is_string( $path ) )
  3322 	if ( $path && is_string( $path ) )
  3057 		$url .= ltrim($path, '/');
  3323 		$url .= ltrim($path, '/');
  3058 
  3324 
  3059 	/**
  3325 	/**
  3060 	 * Filter the user admin URL for the current user.
  3326 	 * Filters the user admin URL for the current user.
  3061 	 *
  3327 	 *
  3062 	 * @since 3.1.0
  3328 	 * @since 3.1.0
  3063 	 *
  3329 	 *
  3064 	 * @param string $url  The complete URL including scheme and path.
  3330 	 * @param string $url  The complete URL including scheme and path.
  3065 	 * @param string $path Path relative to the URL. Blank string if
  3331 	 * @param string $path Path relative to the URL. Blank string if
  3067 	 */
  3333 	 */
  3068 	return apply_filters( 'user_admin_url', $url, $path );
  3334 	return apply_filters( 'user_admin_url', $url, $path );
  3069 }
  3335 }
  3070 
  3336 
  3071 /**
  3337 /**
  3072  * Retrieve the url to the admin area for either the current blog or the network depending on context.
  3338  * Retrieves the URL to the admin area for either the current site or the network depending on context.
  3073  *
  3339  *
  3074  * @since 3.1.0
  3340  * @since 3.1.0
  3075  *
  3341  *
  3076  * @param string $path Optional path relative to the admin url.
  3342  * @param string $path   Optional. Path relative to the admin URL. Default empty.
  3077  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3343  * @param string $scheme Optional. The scheme to use. Default is 'admin', which obeys force_ssl_admin()
  3078  * @return string Admin url link with optional path appended.
  3344  *                       and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3079 */
  3345  * @return string Admin URL link with optional path appended.
  3080 function self_admin_url($path = '', $scheme = 'admin') {
  3346  */
  3081 	if ( is_network_admin() )
  3347 function self_admin_url( $path = '', $scheme = 'admin' ) {
  3082 		return network_admin_url($path, $scheme);
  3348 	if ( is_network_admin() ) {
  3083 	elseif ( is_user_admin() )
  3349 		$url = network_admin_url( $path, $scheme );
  3084 		return user_admin_url($path, $scheme);
  3350 	} elseif ( is_user_admin() ) {
  3085 	else
  3351 		$url = user_admin_url( $path, $scheme );
  3086 		return admin_url($path, $scheme);
  3352 	} else {
  3087 }
  3353 		$url = admin_url( $path, $scheme );
  3088 
  3354 	}
  3089 /**
  3355 
  3090  * Set the scheme for a URL
  3356 	/**
       
  3357 	 * Filters the admin URL for the current site or network depending on context.
       
  3358 	 *
       
  3359 	 * @since 4.9.0
       
  3360 	 *
       
  3361 	 * @param string $url    The complete URL including scheme and path.
       
  3362 	 * @param string $path   Path relative to the URL. Blank string if no path is specified.
       
  3363 	 * @param string $scheme The scheme to use.
       
  3364 	 */
       
  3365 	return apply_filters( 'self_admin_url', $url, $path, $scheme );
       
  3366 }
       
  3367 
       
  3368 /**
       
  3369  * Sets the scheme for a URL.
  3091  *
  3370  *
  3092  * @since 3.4.0
  3371  * @since 3.4.0
  3093  *
  3372  * @since 4.4.0 The 'rest' scheme was added.
  3094  * @param string $url Absolute url that includes a scheme
  3373  *
  3095  * @param string $scheme Optional. Scheme to give $url. Currently 'http', 'https', 'login', 'login_post', 'admin', or 'relative'.
  3374  * @param string      $url    Absolute URL that includes a scheme
       
  3375  * @param string|null $scheme Optional. Scheme to give $url. Currently 'http', 'https', 'login',
       
  3376  *                            'login_post', 'admin', 'relative', 'rest', 'rpc', or null. Default null.
  3096  * @return string $url URL with chosen scheme.
  3377  * @return string $url URL with chosen scheme.
  3097  */
  3378  */
  3098 function set_url_scheme( $url, $scheme = null ) {
  3379 function set_url_scheme( $url, $scheme = null ) {
  3099 	$orig_scheme = $scheme;
  3380 	$orig_scheme = $scheme;
  3100 
  3381 
  3117 	} else {
  3398 	} else {
  3118 		$url = preg_replace( '#^\w+://#', $scheme . '://', $url );
  3399 		$url = preg_replace( '#^\w+://#', $scheme . '://', $url );
  3119 	}
  3400 	}
  3120 
  3401 
  3121 	/**
  3402 	/**
  3122 	 * Filter the resulting URL after setting the scheme.
  3403 	 * Filters the resulting URL after setting the scheme.
  3123 	 *
  3404 	 *
  3124 	 * @since 3.4.0
  3405 	 * @since 3.4.0
  3125 	 *
  3406 	 *
  3126 	 * @param string $url         The complete URL including scheme and path.
  3407 	 * @param string      $url         The complete URL including scheme and path.
  3127 	 * @param string $scheme      Scheme applied to the URL. One of 'http', 'https', or 'relative'.
  3408 	 * @param string      $scheme      Scheme applied to the URL. One of 'http', 'https', or 'relative'.
  3128 	 * @param string $orig_scheme Scheme requested for the URL. One of 'http', 'https', 'login',
  3409 	 * @param string|null $orig_scheme Scheme requested for the URL. One of 'http', 'https', 'login',
  3129 	 *                            'login_post', 'admin', 'rpc', or 'relative'.
  3410 	 *                                 'login_post', 'admin', 'relative', 'rest', 'rpc', or null.
  3130 	 */
  3411 	 */
  3131 	return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );
  3412 	return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );
  3132 }
  3413 }
  3133 
  3414 
  3134 /**
  3415 /**
  3135  * Get the URL to the user's dashboard.
  3416  * Retrieves the URL to the user's dashboard.
  3136  *
  3417  *
  3137  * If a user does not belong to any site, the global user dashboard is used. If the user belongs to the current site,
  3418  * If a user does not belong to any site, the global user dashboard is used. If the user
  3138  * the dashboard for the current site is returned. If the user cannot edit the current site, the dashboard to the user's
  3419  * belongs to the current site, the dashboard for the current site is returned. If the user
  3139  * primary blog is returned.
  3420  * cannot edit the current site, the dashboard to the user's primary site is returned.
  3140  *
  3421  *
  3141  * @since 3.1.0
  3422  * @since 3.1.0
  3142  *
  3423  *
  3143  * @param int $user_id Optional. User ID. Defaults to current user.
  3424  * @param int    $user_id Optional. User ID. Defaults to current user.
  3144  * @param string $path Optional path relative to the dashboard. Use only paths known to both blog and user admins.
  3425  * @param string $path    Optional path relative to the dashboard. Use only paths known to
  3145  * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3426  *                        both site and user admins. Default empty.
  3146  * @return string Dashboard url link with optional path appended.
  3427  * @param string $scheme  The scheme to use. Default is 'admin', which obeys force_ssl_admin()
       
  3428  *                        and is_ssl(). 'http' or 'https' can be passed to force those schemes.
       
  3429  * @return string Dashboard URL link with optional path appended.
  3147  */
  3430  */
  3148 function get_dashboard_url( $user_id = 0, $path = '', $scheme = 'admin' ) {
  3431 function get_dashboard_url( $user_id = 0, $path = '', $scheme = 'admin' ) {
  3149 	$user_id = $user_id ? (int) $user_id : get_current_user_id();
  3432 	$user_id = $user_id ? (int) $user_id : get_current_user_id();
  3150 
  3433 
  3151 	$blogs = get_blogs_of_user( $user_id );
  3434 	$blogs = get_blogs_of_user( $user_id );
  3152 	if ( ! is_super_admin() && empty($blogs) ) {
  3435 	if ( is_multisite() && ! user_can( $user_id, 'manage_network' ) && empty($blogs) ) {
  3153 		$url = user_admin_url( $path, $scheme );
  3436 		$url = user_admin_url( $path, $scheme );
  3154 	} elseif ( ! is_multisite() ) {
  3437 	} elseif ( ! is_multisite() ) {
  3155 		$url = admin_url( $path, $scheme );
  3438 		$url = admin_url( $path, $scheme );
  3156 	} else {
  3439 	} else {
  3157 		$current_blog = get_current_blog_id();
  3440 		$current_blog = get_current_blog_id();
  3158 		if ( $current_blog  && ( is_super_admin( $user_id ) || in_array( $current_blog, array_keys( $blogs ) ) ) ) {
  3441 		if ( $current_blog  && ( user_can( $user_id, 'manage_network' ) || in_array( $current_blog, array_keys( $blogs ) ) ) ) {
  3159 			$url = admin_url( $path, $scheme );
  3442 			$url = admin_url( $path, $scheme );
  3160 		} else {
  3443 		} else {
  3161 			$active = get_active_blog_for_user( $user_id );
  3444 			$active = get_active_blog_for_user( $user_id );
  3162 			if ( $active )
  3445 			if ( $active )
  3163 				$url = get_admin_url( $active->blog_id, $path, $scheme );
  3446 				$url = get_admin_url( $active->blog_id, $path, $scheme );
  3165 				$url = user_admin_url( $path, $scheme );
  3448 				$url = user_admin_url( $path, $scheme );
  3166 		}
  3449 		}
  3167 	}
  3450 	}
  3168 
  3451 
  3169 	/**
  3452 	/**
  3170 	 * Filter the dashboard URL for a user.
  3453 	 * Filters the dashboard URL for a user.
  3171 	 *
  3454 	 *
  3172 	 * @since 3.1.0
  3455 	 * @since 3.1.0
  3173 	 *
  3456 	 *
  3174 	 * @param string $url     The complete URL including scheme and path.
  3457 	 * @param string $url     The complete URL including scheme and path.
  3175 	 * @param int    $user_id The user ID.
  3458 	 * @param int    $user_id The user ID.
  3179 	 */
  3462 	 */
  3180 	return apply_filters( 'user_dashboard_url', $url, $user_id, $path, $scheme);
  3463 	return apply_filters( 'user_dashboard_url', $url, $user_id, $path, $scheme);
  3181 }
  3464 }
  3182 
  3465 
  3183 /**
  3466 /**
  3184  * Get the URL to the user's profile editor.
  3467  * Retrieves the URL to the user's profile editor.
  3185  *
  3468  *
  3186  * @since 3.1.0
  3469  * @since 3.1.0
  3187  *
  3470  *
  3188  * @param int    $user_id Optional. User ID. Defaults to current user.
  3471  * @param int    $user_id Optional. User ID. Defaults to current user.
  3189  * @param string $scheme  The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl().
  3472  * @param string $scheme  Optional. The scheme to use. Default is 'admin', which obeys force_ssl_admin()
  3190  *                        'http' or 'https' can be passed to force those schemes.
  3473  *                        and is_ssl(). 'http' or 'https' can be passed to force those schemes.
  3191  * @return string Dashboard url link with optional path appended.
  3474  * @return string Dashboard URL link with optional path appended.
  3192  */
  3475  */
  3193 function get_edit_profile_url( $user_id = 0, $scheme = 'admin' ) {
  3476 function get_edit_profile_url( $user_id = 0, $scheme = 'admin' ) {
  3194 	$user_id = $user_id ? (int) $user_id : get_current_user_id();
  3477 	$user_id = $user_id ? (int) $user_id : get_current_user_id();
  3195 
  3478 
  3196 	if ( is_user_admin() )
  3479 	if ( is_user_admin() )
  3199 		$url = network_admin_url( 'profile.php', $scheme );
  3482 		$url = network_admin_url( 'profile.php', $scheme );
  3200 	else
  3483 	else
  3201 		$url = get_dashboard_url( $user_id, 'profile.php', $scheme );
  3484 		$url = get_dashboard_url( $user_id, 'profile.php', $scheme );
  3202 
  3485 
  3203 	/**
  3486 	/**
  3204 	 * Filter the URL for a user's profile editor.
  3487 	 * Filters the URL for a user's profile editor.
  3205 	 *
  3488 	 *
  3206 	 * @since 3.1.0
  3489 	 * @since 3.1.0
  3207 	 *
  3490 	 *
  3208 	 * @param string $url     The complete URL including scheme and path.
  3491 	 * @param string $url     The complete URL including scheme and path.
  3209 	 * @param int    $user_id The user ID.
  3492 	 * @param int    $user_id The user ID.
  3212 	 */
  3495 	 */
  3213 	return apply_filters( 'edit_profile_url', $url, $user_id, $scheme);
  3496 	return apply_filters( 'edit_profile_url', $url, $user_id, $scheme);
  3214 }
  3497 }
  3215 
  3498 
  3216 /**
  3499 /**
  3217  * Output rel=canonical for singular queries.
  3500  * Returns the canonical URL for a post.
       
  3501  *
       
  3502  * When the post is the same as the current requested page the function will handle the
       
  3503  * pagination arguments too.
       
  3504  *
       
  3505  * @since 4.6.0
       
  3506  *
       
  3507  * @param int|WP_Post $post Optional. Post ID or object. Default is global `$post`.
       
  3508  * @return string|false The canonical URL, or false if the post does not exist or has not
       
  3509  *                      been published yet.
       
  3510  */
       
  3511 function wp_get_canonical_url( $post = null ) {
       
  3512 	$post = get_post( $post );
       
  3513 
       
  3514 	if ( ! $post ) {
       
  3515 		return false;
       
  3516 	}
       
  3517 
       
  3518 	if ( 'publish' !== $post->post_status ) {
       
  3519 		return false;
       
  3520 	}
       
  3521 
       
  3522 	$canonical_url = get_permalink( $post );
       
  3523 
       
  3524 	// If a canonical is being generated for the current page, make sure it has pagination if needed.
       
  3525 	if ( $post->ID === get_queried_object_id() ) {
       
  3526 		$page = get_query_var( 'page', 0 );
       
  3527 		if ( $page >= 2 ) {
       
  3528 			if ( '' == get_option( 'permalink_structure' ) ) {
       
  3529 				$canonical_url = add_query_arg( 'page', $page, $canonical_url );
       
  3530 			} else {
       
  3531 				$canonical_url = trailingslashit( $canonical_url ) . user_trailingslashit( $page, 'single_paged' );
       
  3532 			}
       
  3533 		}
       
  3534 
       
  3535 		$cpage = get_query_var( 'cpage', 0 );
       
  3536 		if ( $cpage ) {
       
  3537 			$canonical_url = get_comments_pagenum_link( $cpage );
       
  3538 		}
       
  3539 	}
       
  3540 
       
  3541 	/**
       
  3542 	 * Filters the canonical URL for a post.
       
  3543 	 *
       
  3544 	 * @since 4.6.0
       
  3545 	 *
       
  3546 	 * @param string  $canonical_url The post's canonical URL.
       
  3547 	 * @param WP_Post $post          Post object.
       
  3548 	 */
       
  3549 	return apply_filters( 'get_canonical_url', $canonical_url, $post );
       
  3550 }
       
  3551 
       
  3552 /**
       
  3553  * Outputs rel=canonical for singular queries.
  3218  *
  3554  *
  3219  * @since 2.9.0
  3555  * @since 2.9.0
  3220 */
  3556  * @since 4.6.0 Adjusted to use wp_get_canonical_url().
       
  3557  */
  3221 function rel_canonical() {
  3558 function rel_canonical() {
  3222 	if ( !is_singular() )
  3559 	if ( ! is_singular() ) {
  3223 		return;
  3560 		return;
  3224 
  3561 	}
  3225 	global $wp_the_query;
  3562 
  3226 	if ( !$id = $wp_the_query->get_queried_object_id() )
  3563 	$id = get_queried_object_id();
       
  3564 
       
  3565 	if ( 0 === $id ) {
  3227 		return;
  3566 		return;
  3228 
  3567 	}
  3229 	$link = get_permalink( $id );
  3568 
  3230 
  3569 	$url = wp_get_canonical_url( $id );
  3231 	if ( $page = get_query_var('cpage') )
  3570 
  3232 		$link = get_comments_pagenum_link( $page );
  3571 	if ( ! empty( $url ) ) {
  3233 
  3572 		echo '<link rel="canonical" href="' . esc_url( $url ) . '" />' . "\n";
  3234 	echo "<link rel='canonical' href='$link' />\n";
  3573 	}
  3235 }
  3574 }
  3236 
  3575 
  3237 /**
  3576 /**
  3238  * Return a shortlink for a post, page, attachment, or blog.
  3577  * Returns a shortlink for a post, page, attachment, or site.
  3239  *
  3578  *
  3240  * This function exists to provide a shortlink tag that all themes and plugins can target. A plugin must hook in to
  3579  * This function exists to provide a shortlink tag that all themes and plugins can target.
  3241  * provide the actual shortlinks. Default shortlink support is limited to providing ?p= style links for posts.
  3580  * A plugin must hook in to provide the actual shortlinks. Default shortlink support is
  3242  * Plugins can short-circuit this function via the pre_get_shortlink filter or filter the output
  3581  * limited to providing ?p= style links for posts. Plugins can short-circuit this function
  3243  * via the get_shortlink filter.
  3582  * via the {@see 'pre_get_shortlink'} filter or filter the output via the {@see 'get_shortlink'}
       
  3583  * filter.
  3244  *
  3584  *
  3245  * @since 3.0.0.
  3585  * @since 3.0.0.
  3246  *
  3586  *
  3247  * @param int $id A post or blog id. Default is 0, which means the current post or blog.
  3587  * @param int    $id          Optional. A post or site id. Default is 0, which means the current post or site.
  3248  * @param string $context Whether the id is a 'blog' id, 'post' id, or 'media' id. If 'post', the post_type of the post is consulted. If 'query', the current query is consulted to determine the id and context. Default is 'post'.
  3588  * @param string $context     Optional. Whether the id is a 'site' id, 'post' id, or 'media' id. If 'post',
  3249  * @param bool $allow_slugs Whether to allow post slugs in the shortlink. It is up to the plugin how and whether to honor this.
  3589  *                            the post_type of the post is consulted. If 'query', the current query is consulted
  3250  * @return string A shortlink or an empty string if no shortlink exists for the requested resource or if shortlinks are not enabled.
  3590  *                            to determine the id and context. Default 'post'.
  3251  */
  3591  * @param bool   $allow_slugs Optional. Whether to allow post slugs in the shortlink. It is up to the plugin how
  3252 function wp_get_shortlink($id = 0, $context = 'post', $allow_slugs = true) {
  3592  *                            and whether to honor this. Default true.
  3253 	/**
  3593  * @return string A shortlink or an empty string if no shortlink exists for the requested resource or if shortlinks
  3254 	 * Filter whether to preempt generating a shortlink for the given post.
  3594  *                are not enabled.
       
  3595  */
       
  3596 function wp_get_shortlink( $id = 0, $context = 'post', $allow_slugs = true ) {
       
  3597 	/**
       
  3598 	 * Filters whether to preempt generating a shortlink for the given post.
  3255 	 *
  3599 	 *
  3256 	 * Passing a truthy value to the filter will effectively short-circuit the
  3600 	 * Passing a truthy value to the filter will effectively short-circuit the
  3257 	 * shortlink-generation process, returning that value instead.
  3601 	 * shortlink-generation process, returning that value instead.
  3258 	 *
  3602 	 *
  3259 	 * @since 3.0.0
  3603 	 * @since 3.0.0
  3263 	 * @param string      $context     The context for the link. One of 'post' or 'query',
  3607 	 * @param string      $context     The context for the link. One of 'post' or 'query',
  3264 	 * @param bool        $allow_slugs Whether to allow post slugs in the shortlink.
  3608 	 * @param bool        $allow_slugs Whether to allow post slugs in the shortlink.
  3265 	 */
  3609 	 */
  3266 	$shortlink = apply_filters( 'pre_get_shortlink', false, $id, $context, $allow_slugs );
  3610 	$shortlink = apply_filters( 'pre_get_shortlink', false, $id, $context, $allow_slugs );
  3267 
  3611 
  3268 	if ( false !== $shortlink )
  3612 	if ( false !== $shortlink ) {
  3269 		return $shortlink;
  3613 		return $shortlink;
  3270 
  3614 	}
  3271 	global $wp_query;
  3615 
  3272 	$post_id = 0;
  3616 	$post_id = 0;
  3273 	if ( 'query' == $context && is_singular() ) {
  3617 	if ( 'query' == $context && is_singular() ) {
  3274 		$post_id = $wp_query->get_queried_object_id();
  3618 		$post_id = get_queried_object_id();
  3275 		$post = get_post( $post_id );
  3619 		$post = get_post( $post_id );
  3276 	} elseif ( 'post' == $context ) {
  3620 	} elseif ( 'post' == $context ) {
  3277 		$post = get_post( $id );
  3621 		$post = get_post( $id );
  3278 		if ( ! empty( $post->ID ) )
  3622 		if ( ! empty( $post->ID ) )
  3279 			$post_id = $post->ID;
  3623 			$post_id = $post->ID;
  3291 			$shortlink = home_url( '?p=' . $post_id );
  3635 			$shortlink = home_url( '?p=' . $post_id );
  3292 		}
  3636 		}
  3293 	}
  3637 	}
  3294 
  3638 
  3295 	/**
  3639 	/**
  3296 	 * Filter the shortlink for a post.
  3640 	 * Filters the shortlink for a post.
  3297 	 *
  3641 	 *
  3298 	 * @since 3.0.0
  3642 	 * @since 3.0.0
  3299 	 *
  3643 	 *
  3300 	 * @param string $shortlink   Shortlink URL.
  3644 	 * @param string $shortlink   Shortlink URL.
  3301 	 * @param int    $id          Post ID, or 0 for the current post.
  3645 	 * @param int    $id          Post ID, or 0 for the current post.
  3304 	 */
  3648 	 */
  3305 	return apply_filters( 'get_shortlink', $shortlink, $id, $context, $allow_slugs );
  3649 	return apply_filters( 'get_shortlink', $shortlink, $id, $context, $allow_slugs );
  3306 }
  3650 }
  3307 
  3651 
  3308 /**
  3652 /**
  3309  *  Inject rel=shortlink into head if a shortlink is defined for the current page.
  3653  * Injects rel=shortlink into the head if a shortlink is defined for the current page.
  3310  *
  3654  *
  3311  *  Attached to the wp_head action.
  3655  * Attached to the {@see 'wp_head'} action.
  3312  *
  3656  *
  3313  * @since 3.0.0
  3657  * @since 3.0.0
  3314  */
  3658  */
  3315 function wp_shortlink_wp_head() {
  3659 function wp_shortlink_wp_head() {
  3316 	$shortlink = wp_get_shortlink( 0, 'query' );
  3660 	$shortlink = wp_get_shortlink( 0, 'query' );
  3320 
  3664 
  3321 	echo "<link rel='shortlink' href='" . esc_url( $shortlink ) . "' />\n";
  3665 	echo "<link rel='shortlink' href='" . esc_url( $shortlink ) . "' />\n";
  3322 }
  3666 }
  3323 
  3667 
  3324 /**
  3668 /**
  3325  * Send a Link: rel=shortlink header if a shortlink is defined for the current page.
  3669  * Sends a Link: rel=shortlink header if a shortlink is defined for the current page.
  3326  *
  3670  *
  3327  * Attached to the wp action.
  3671  * Attached to the {@see 'wp'} action.
  3328  *
  3672  *
  3329  * @since 3.0.0
  3673  * @since 3.0.0
  3330  */
  3674  */
  3331 function wp_shortlink_header() {
  3675 function wp_shortlink_header() {
  3332 	if ( headers_sent() )
  3676 	if ( headers_sent() )
  3339 
  3683 
  3340 	header('Link: <' . $shortlink . '>; rel=shortlink', false);
  3684 	header('Link: <' . $shortlink . '>; rel=shortlink', false);
  3341 }
  3685 }
  3342 
  3686 
  3343 /**
  3687 /**
  3344  * Display the Short Link for a Post
  3688  * Displays the shortlink for a post.
  3345  *
  3689  *
  3346  * Must be called from inside "The Loop"
  3690  * Must be called from inside "The Loop"
  3347  *
  3691  *
  3348  * Call like the_shortlink(__('Shortlinkage FTW'))
  3692  * Call like the_shortlink( __( 'Shortlinkage FTW' ) )
  3349  *
  3693  *
  3350  * @since 3.0.0
  3694  * @since 3.0.0
  3351  *
  3695  *
  3352  * @param string $text Optional The link text or HTML to be displayed. Defaults to 'This is the short link.'
  3696  * @param string $text   Optional The link text or HTML to be displayed. Defaults to 'This is the short link.'
  3353  * @param string $title Optional The tooltip for the link. Must be sanitized. Defaults to the sanitized post title.
  3697  * @param string $title  Optional The tooltip for the link. Must be sanitized. Defaults to the sanitized post title.
  3354  * @param string $before Optional HTML to display before the link.
  3698  * @param string $before Optional HTML to display before the link. Default empty.
  3355  * @param string $after Optional HTML to display after the link.
  3699  * @param string $after  Optional HTML to display after the link. Default empty.
  3356  */
  3700  */
  3357 function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) {
  3701 function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) {
  3358 	$post = get_post();
  3702 	$post = get_post();
  3359 
  3703 
  3360 	if ( empty( $text ) )
  3704 	if ( empty( $text ) )
  3367 
  3711 
  3368 	if ( !empty( $shortlink ) ) {
  3712 	if ( !empty( $shortlink ) ) {
  3369 		$link = '<a rel="shortlink" href="' . esc_url( $shortlink ) . '" title="' . $title . '">' . $text . '</a>';
  3713 		$link = '<a rel="shortlink" href="' . esc_url( $shortlink ) . '" title="' . $title . '">' . $text . '</a>';
  3370 
  3714 
  3371 		/**
  3715 		/**
  3372 		 * Filter the shortlink anchor tag for a post.
  3716 		 * Filters the short link anchor tag for a post.
  3373 		 *
  3717 		 *
  3374 		 * @since 3.0.0
  3718 		 * @since 3.0.0
  3375 		 *
  3719 		 *
  3376 		 * @param string $link      Shortlink anchor tag.
  3720 		 * @param string $link      Shortlink anchor tag.
  3377 		 * @param string $shortlink Shortlink URL.
  3721 		 * @param string $shortlink Shortlink URL.
  3383 	}
  3727 	}
  3384 }
  3728 }
  3385 
  3729 
  3386 
  3730 
  3387 /**
  3731 /**
  3388  * Retrieve the avatar URL.
  3732  * Retrieves the avatar URL.
  3389  *
  3733  *
  3390  * @since 4.2.0
  3734  * @since 4.2.0
  3391  *
  3735  *
  3392  * @param mixed $id_or_email The Gravatar to retrieve a URL for. Accepts a user_id, gravatar md5 hash,
  3736  * @param mixed $id_or_email The Gravatar to retrieve a URL for. Accepts a user_id, gravatar md5 hash,
  3393  *                           user email, WP_User object, WP_Post object, or comment object.
  3737  *                           user email, WP_User object, WP_Post object, or WP_Comment object.
  3394  * @param array $args {
  3738  * @param array $args {
  3395  *     Optional. Arguments to return instead of the default arguments.
  3739  *     Optional. Arguments to return instead of the default arguments.
  3396  *
  3740  *
  3397  *     @type int    $size           Height and width of the avatar in pixels. Default 96.
  3741  *     @type int    $size           Height and width of the avatar in pixels. Default 96.
  3398  *     @type string $default        URL for the default image or a default type. Accepts '404' (return
  3742  *     @type string $default        URL for the default image or a default type. Accepts '404' (return
  3399  *                                  a 404 instead of a default image), 'retro' (8bit), 'monsterid' (monster),
  3743  *                                  a 404 instead of a default image), 'retro' (8bit), 'monsterid' (monster),
  3400  *                                  'wavatar' (cartoon face), 'indenticon' (the "quilt"), 'mystery', 'mm',
  3744  *                                  'wavatar' (cartoon face), 'indenticon' (the "quilt"), 'mystery', 'mm',
  3401  *                                  or 'mysterman' (The Oyster Man), 'blank' (transparent GIF), or
  3745  *                                  or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF), or
  3402  *                                  'gravatar_default' (the Gravatar logo). Default is the value of the
  3746  *                                  'gravatar_default' (the Gravatar logo). Default is the value of the
  3403  *                                  'avatar_default' option, with a fallback of 'mystery'.
  3747  *                                  'avatar_default' option, with a fallback of 'mystery'.
  3404  *     @type bool   $force_default  Whether to always show the default image, never the Gravatar. Default false.
  3748  *     @type bool   $force_default  Whether to always show the default image, never the Gravatar. Default false.
  3405  *     @type string $rating         What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are
  3749  *     @type string $rating         What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are
  3406  *                                  judged in that order. Default is the value of the 'avatar_rating' option.
  3750  *                                  judged in that order. Default is the value of the 'avatar_rating' option.
  3415 	$args = get_avatar_data( $id_or_email, $args );
  3759 	$args = get_avatar_data( $id_or_email, $args );
  3416 	return $args['url'];
  3760 	return $args['url'];
  3417 }
  3761 }
  3418 
  3762 
  3419 /**
  3763 /**
  3420  * Retrieve default data about the avatar.
  3764  * Retrieves default data about the avatar.
  3421  *
  3765  *
  3422  * @since 4.2.0
  3766  * @since 4.2.0
  3423  *
  3767  *
  3424  * @param mixed $id_or_email The Gravatar to check the data against. Accepts a user_id, gravatar md5 hash,
  3768  * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
  3425  *                           user email, WP_User object, WP_Post object, or comment object.
  3769  *                            user email, WP_User object, WP_Post object, or WP_Comment object.
  3426  * @param array $args {
  3770  * @param array $args {
  3427  *     Optional. Arguments to return instead of the default arguments.
  3771  *     Optional. Arguments to return instead of the default arguments.
  3428  *
  3772  *
  3429  *     @type int    $size           Height and width of the avatar image file in pixels. Default 96.
  3773  *     @type int    $size           Height and width of the avatar image file in pixels. Default 96.
  3430  *     @type int    $height         Display height of the avatar in pixels. Defaults to $size.
  3774  *     @type int    $height         Display height of the avatar in pixels. Defaults to $size.
  3431  *     @type int    $width          Display width of the avatar in pixels. Defaults to $size.
  3775  *     @type int    $width          Display width of the avatar in pixels. Defaults to $size.
  3432  *     @type string $default        URL for the default image or a default type. Accepts '404' (return
  3776  *     @type string $default        URL for the default image or a default type. Accepts '404' (return
  3433  *                                  a 404 instead of a default image), 'retro' (8bit), 'monsterid' (monster),
  3777  *                                  a 404 instead of a default image), 'retro' (8bit), 'monsterid' (monster),
  3434  *                                  'wavatar' (cartoon face), 'indenticon' (the "quilt"), 'mystery', 'mm',
  3778  *                                  'wavatar' (cartoon face), 'indenticon' (the "quilt"), 'mystery', 'mm',
  3435  *                                  or 'mysterman' (The Oyster Man), 'blank' (transparent GIF), or
  3779  *                                  or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF), or
  3436  *                                  'gravatar_default' (the Gravatar logo). Default is the value of the
  3780  *                                  'gravatar_default' (the Gravatar logo). Default is the value of the
  3437  *                                  'avatar_default' option, with a fallback of 'mystery'.
  3781  *                                  'avatar_default' option, with a fallback of 'mystery'.
  3438  *     @type bool   $force_default  Whether to always show the default image, never the Gravatar. Default false.
  3782  *     @type bool   $force_default  Whether to always show the default image, never the Gravatar. Default false.
  3439  *     @type string $rating         What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are
  3783  *     @type string $rating         What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are
  3440  *                                  judged in that order. Default is the value of the 'avatar_rating' option.
  3784  *                                  judged in that order. Default is the value of the 'avatar_rating' option.
  3512 	$args['rating'] = strtolower( $args['rating'] );
  3856 	$args['rating'] = strtolower( $args['rating'] );
  3513 
  3857 
  3514 	$args['found_avatar'] = false;
  3858 	$args['found_avatar'] = false;
  3515 
  3859 
  3516 	/**
  3860 	/**
  3517 	 * Filter whether to retrieve the avatar URL early.
  3861 	 * Filters whether to retrieve the avatar URL early.
  3518 	 *
  3862 	 *
  3519 	 * Passing a non-null value in the 'url' member of the return array will
  3863 	 * Passing a non-null value in the 'url' member of the return array will
  3520 	 * effectively short circuit get_avatar_data(), passing the value through
  3864 	 * effectively short circuit get_avatar_data(), passing the value through
  3521 	 * the {@see 'get_avatar_data'} filter and returning early.
  3865 	 * the {@see 'get_avatar_data'} filter and returning early.
  3522 	 *
  3866 	 *
  3523 	 * @since 4.2.0
  3867 	 * @since 4.2.0
  3524 	 *
  3868 	 *
  3525 	 * @param array             $args          Arguments passed to get_avatar_data(), after processing.
  3869 	 * @param array  $args        Arguments passed to get_avatar_data(), after processing.
  3526 	 * @param int|object|string $id_or_email   A user ID, email address, or comment object.
  3870 	 * @param mixed  $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
       
  3871 	 *                            user email, WP_User object, WP_Post object, or WP_Comment object.
  3527 	 */
  3872 	 */
  3528 	$args = apply_filters( 'pre_get_avatar_data', $args, $id_or_email );
  3873 	$args = apply_filters( 'pre_get_avatar_data', $args, $id_or_email );
  3529 
  3874 
  3530 	if ( isset( $args['url'] ) && ! is_null( $args['url'] ) ) {
  3875 	if ( isset( $args['url'] ) && ! is_null( $args['url'] ) ) {
  3531 		/** This filter is documented in wp-includes/link-template.php */
  3876 		/** This filter is documented in wp-includes/link-template.php */
  3532 		return apply_filters( 'get_avatar_data', $args, $id_or_email );
  3877 		return apply_filters( 'get_avatar_data', $args, $id_or_email );
  3533 	}
  3878 	}
  3534 
  3879 
  3535 	$email_hash = '';
  3880 	$email_hash = '';
  3536 	$user = $email = false;
  3881 	$user = $email = false;
       
  3882 
       
  3883 	if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
       
  3884 		$id_or_email = get_comment( $id_or_email );
       
  3885 	}
  3537 
  3886 
  3538 	// Process the user identifier.
  3887 	// Process the user identifier.
  3539 	if ( is_numeric( $id_or_email ) ) {
  3888 	if ( is_numeric( $id_or_email ) ) {
  3540 		$user = get_user_by( 'id', absint( $id_or_email ) );
  3889 		$user = get_user_by( 'id', absint( $id_or_email ) );
  3541 	} elseif ( is_string( $id_or_email ) ) {
  3890 	} elseif ( is_string( $id_or_email ) ) {
  3550 		// User Object
  3899 		// User Object
  3551 		$user = $id_or_email;
  3900 		$user = $id_or_email;
  3552 	} elseif ( $id_or_email instanceof WP_Post ) {
  3901 	} elseif ( $id_or_email instanceof WP_Post ) {
  3553 		// Post Object
  3902 		// Post Object
  3554 		$user = get_user_by( 'id', (int) $id_or_email->post_author );
  3903 		$user = get_user_by( 'id', (int) $id_or_email->post_author );
  3555 	} elseif ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
  3904 	} elseif ( $id_or_email instanceof WP_Comment ) {
  3556 		// Comment Object
       
  3557 
       
  3558 		/**
  3905 		/**
  3559 		 * Filter the list of allowed comment types for retrieving avatars.
  3906 		 * Filters the list of allowed comment types for retrieving avatars.
  3560 		 *
  3907 		 *
  3561 		 * @since 3.0.0
  3908 		 * @since 3.0.0
  3562 		 *
  3909 		 *
  3563 		 * @param array $types An array of content types. Default only contains 'comment'.
  3910 		 * @param array $types An array of content types. Default only contains 'comment'.
  3564 		 */
  3911 		 */
  3599 		'd' => $args['default'],
  3946 		'd' => $args['default'],
  3600 		'f' => $args['force_default'] ? 'y' : false,
  3947 		'f' => $args['force_default'] ? 'y' : false,
  3601 		'r' => $args['rating'],
  3948 		'r' => $args['rating'],
  3602 	);
  3949 	);
  3603 
  3950 
  3604 	$url = sprintf( 'http://%d.gravatar.com/avatar/%s', $gravatar_server, $email_hash );
  3951 	if ( is_ssl() ) {
       
  3952 		$url = 'https://secure.gravatar.com/avatar/' . $email_hash;
       
  3953 	} else {
       
  3954 		$url = sprintf( 'http://%d.gravatar.com/avatar/%s', $gravatar_server, $email_hash );
       
  3955 	}
  3605 
  3956 
  3606 	$url = add_query_arg(
  3957 	$url = add_query_arg(
  3607 		rawurlencode_deep( array_filter( $url_args ) ),
  3958 		rawurlencode_deep( array_filter( $url_args ) ),
  3608 		set_url_scheme( $url, $args['scheme'] )
  3959 		set_url_scheme( $url, $args['scheme'] )
  3609 	);
  3960 	);
  3610 
  3961 
  3611 	/**
  3962 	/**
  3612 	 * Filter the avatar URL.
  3963 	 * Filters the avatar URL.
  3613 	 *
  3964 	 *
  3614 	 * @since 4.2.0
  3965 	 * @since 4.2.0
  3615 	 *
  3966 	 *
  3616 	 * @param string            $url         The URL of the avatar.
  3967 	 * @param string $url         The URL of the avatar.
  3617 	 * @param int|object|string $id_or_email A user ID, email address, or comment object.
  3968 	 * @param mixed  $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
  3618 	 * @param array             $args        Arguments passed to get_avatar_data(), after processing.
  3969 	 *                            user email, WP_User object, WP_Post object, or WP_Comment object.
       
  3970 	 * @param array  $args        Arguments passed to get_avatar_data(), after processing.
  3619 	 */
  3971 	 */
  3620 	$args['url'] = apply_filters( 'get_avatar_url', $url, $id_or_email, $args );
  3972 	$args['url'] = apply_filters( 'get_avatar_url', $url, $id_or_email, $args );
  3621 
  3973 
  3622 	/**
  3974 	/**
  3623 	 * Filter the avatar data.
  3975 	 * Filters the avatar data.
  3624 	 *
  3976 	 *
  3625 	 * @since 4.2.0
  3977 	 * @since 4.2.0
  3626 	 *
  3978 	 *
  3627 	 * @param array             $args        Arguments passed to get_avatar_data(), after processing.
  3979 	 * @param array  $args        Arguments passed to get_avatar_data(), after processing.
  3628 	 * @param int|object|string $id_or_email A user ID, email address, or comment object.
  3980 	 * @param mixed  $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
       
  3981 	 *                            user email, WP_User object, WP_Post object, or WP_Comment object.
  3629 	 */
  3982 	 */
  3630 	return apply_filters( 'get_avatar_data', $args, $id_or_email );
  3983 	return apply_filters( 'get_avatar_data', $args, $id_or_email );
  3631 }
  3984 }
       
  3985 
       
  3986 /**
       
  3987  * Retrieves the URL of a file in the theme.
       
  3988  *
       
  3989  * Searches in the stylesheet directory before the template directory so themes
       
  3990  * which inherit from a parent theme can just override one file.
       
  3991  *
       
  3992  * @since 4.7.0
       
  3993  *
       
  3994  * @param string $file Optional. File to search for in the stylesheet directory.
       
  3995  * @return string The URL of the file.
       
  3996  */
       
  3997 function get_theme_file_uri( $file = '' ) {
       
  3998 	$file = ltrim( $file, '/' );
       
  3999 
       
  4000 	if ( empty( $file ) ) {
       
  4001 		$url = get_stylesheet_directory_uri();
       
  4002 	} elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
       
  4003 		$url = get_stylesheet_directory_uri() . '/' . $file;
       
  4004 	} else {
       
  4005 		$url = get_template_directory_uri() . '/' . $file;
       
  4006 	}
       
  4007 
       
  4008 	/**
       
  4009 	 * Filters the URL to a file in the theme.
       
  4010 	 *
       
  4011 	 * @since 4.7.0
       
  4012 	 *
       
  4013 	 * @param string $url  The file URL.
       
  4014 	 * @param string $file The requested file to search for.
       
  4015 	 */
       
  4016 	return apply_filters( 'theme_file_uri', $url, $file );
       
  4017 }
       
  4018 
       
  4019 /**
       
  4020  * Retrieves the URL of a file in the parent theme.
       
  4021  *
       
  4022  * @since 4.7.0
       
  4023  *
       
  4024  * @param string $file Optional. File to return the URL for in the template directory.
       
  4025  * @return string The URL of the file.
       
  4026  */
       
  4027 function get_parent_theme_file_uri( $file = '' ) {
       
  4028 	$file = ltrim( $file, '/' );
       
  4029 
       
  4030 	if ( empty( $file ) ) {
       
  4031 		$url = get_template_directory_uri();
       
  4032 	} else {
       
  4033 		$url = get_template_directory_uri() . '/' . $file;
       
  4034 	}
       
  4035 
       
  4036 	/**
       
  4037 	 * Filters the URL to a file in the parent theme.
       
  4038 	 *
       
  4039 	 * @since 4.7.0
       
  4040 	 *
       
  4041 	 * @param string $url  The file URL.
       
  4042 	 * @param string $file The requested file to search for.
       
  4043 	 */
       
  4044 	return apply_filters( 'parent_theme_file_uri', $url, $file );
       
  4045 }
       
  4046 
       
  4047 /**
       
  4048  * Retrieves the path of a file in the theme.
       
  4049  *
       
  4050  * Searches in the stylesheet directory before the template directory so themes
       
  4051  * which inherit from a parent theme can just override one file.
       
  4052  *
       
  4053  * @since 4.7.0
       
  4054  *
       
  4055  * @param string $file Optional. File to search for in the stylesheet directory.
       
  4056  * @return string The path of the file.
       
  4057  */
       
  4058 function get_theme_file_path( $file = '' ) {
       
  4059 	$file = ltrim( $file, '/' );
       
  4060 
       
  4061 	if ( empty( $file ) ) {
       
  4062 		$path = get_stylesheet_directory();
       
  4063 	} elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
       
  4064 		$path = get_stylesheet_directory() . '/' . $file;
       
  4065 	} else {
       
  4066 		$path = get_template_directory() . '/' . $file;
       
  4067 	}
       
  4068 
       
  4069 	/**
       
  4070 	 * Filters the path to a file in the theme.
       
  4071 	 *
       
  4072 	 * @since 4.7.0
       
  4073 	 *
       
  4074 	 * @param string $path The file path.
       
  4075 	 * @param string $file The requested file to search for.
       
  4076 	 */
       
  4077 	return apply_filters( 'theme_file_path', $path, $file );
       
  4078 }
       
  4079 
       
  4080 /**
       
  4081  * Retrieves the path of a file in the parent theme.
       
  4082  *
       
  4083  * @since 4.7.0
       
  4084  *
       
  4085  * @param string $file Optional. File to return the path for in the template directory.
       
  4086  * @return string The path of the file.
       
  4087  */
       
  4088 function get_parent_theme_file_path( $file = '' ) {
       
  4089 	$file = ltrim( $file, '/' );
       
  4090 
       
  4091 	if ( empty( $file ) ) {
       
  4092 		$path = get_template_directory();
       
  4093 	} else {
       
  4094 		$path = get_template_directory() . '/' . $file;
       
  4095 	}
       
  4096 
       
  4097 	/**
       
  4098 	 * Filters the path to a file in the parent theme.
       
  4099 	 *
       
  4100 	 * @since 4.7.0
       
  4101 	 *
       
  4102 	 * @param string $path The file path.
       
  4103 	 * @param string $file The requested file to search for.
       
  4104 	 */
       
  4105 	return apply_filters( 'parent_theme_file_path', $path, $file );
       
  4106 }
       
  4107 
       
  4108 /**
       
  4109  * Retrieves the URL to the privacy policy page.
       
  4110  *
       
  4111  * @since 4.9.6
       
  4112  *
       
  4113  * @return string The URL to the privacy policy page. Empty string if it doesn't exist.
       
  4114  */
       
  4115 function get_privacy_policy_url() {
       
  4116 	$url            = '';
       
  4117 	$policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' );
       
  4118 
       
  4119 	if ( ! empty( $policy_page_id ) && get_post_status( $policy_page_id ) === 'publish' ) {
       
  4120 		$url = (string) get_permalink( $policy_page_id );
       
  4121 	}
       
  4122 
       
  4123 	/**
       
  4124 	 * Filters the URL of the privacy policy page.
       
  4125 	 *
       
  4126 	 * @since 4.9.6
       
  4127 	 *
       
  4128 	 * @param string $url            The URL to the privacy policy page. Empty string
       
  4129 	 *                               if it doesn't exist.
       
  4130 	 * @param int    $policy_page_id The ID of privacy policy page.
       
  4131 	 */
       
  4132 	return apply_filters( 'privacy_policy_url', $url, $policy_page_id );
       
  4133 }
       
  4134 
       
  4135 /**
       
  4136  * Displays the privacy policy link with formatting, when applicable.
       
  4137  *
       
  4138  * @since 4.9.6
       
  4139  *
       
  4140  * @param string $before Optional. Display before privacy policy link. Default empty.
       
  4141  * @param string $after  Optional. Display after privacy policy link. Default empty.
       
  4142  */
       
  4143 function the_privacy_policy_link( $before = '', $after = '' ) {
       
  4144 	echo get_the_privacy_policy_link( $before, $after );
       
  4145 }
       
  4146 
       
  4147 /**
       
  4148  * Returns the privacy policy link with formatting, when applicable.
       
  4149  *
       
  4150  * @since 4.9.6
       
  4151  *
       
  4152  * @param string $before Optional. Display before privacy policy link. Default empty.
       
  4153  * @param string $after  Optional. Display after privacy policy link. Default empty.
       
  4154  *
       
  4155  * @return string Markup for the link and surrounding elements. Empty string if it
       
  4156  *                doesn't exist.
       
  4157  */
       
  4158 function get_the_privacy_policy_link( $before = '', $after = '' ) {
       
  4159 	$link               = '';
       
  4160 	$privacy_policy_url = get_privacy_policy_url();
       
  4161 	$policy_page_id     = (int) get_option( 'wp_page_for_privacy_policy' );
       
  4162 	$page_title         = ( $policy_page_id ) ? get_the_title( $policy_page_id ) : '';
       
  4163 
       
  4164 	if ( $privacy_policy_url && $page_title ) {
       
  4165 		$link = sprintf(
       
  4166 			'<a class="privacy-policy-link" href="%s">%s</a>',
       
  4167 			esc_url( $privacy_policy_url ),
       
  4168 			esc_html( $page_title )
       
  4169 		);
       
  4170 	}
       
  4171 
       
  4172 	/**
       
  4173 	 * Filters the privacy policy link.
       
  4174 	 *
       
  4175 	 * @since 4.9.6
       
  4176 	 *
       
  4177 	 * @param string $link               The privacy policy link. Empty string if it
       
  4178 	 *                                   doesn't exist.
       
  4179 	 * @param string $privacy_policy_url The URL of the privacy policy. Empty string
       
  4180 	 *                                   if it doesn't exist.
       
  4181 	 */
       
  4182 	$link = apply_filters( 'the_privacy_policy_link', $link, $privacy_policy_url );
       
  4183 
       
  4184 	if ( $link ) {
       
  4185 		return $before . $link . $after;
       
  4186 	}
       
  4187 
       
  4188 	return '';
       
  4189 }