[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> link-template.php (source)

   1  <?php
   2  /**
   3   * WordPress Link Template Functions
   4   *
   5   * @package WordPress
   6   * @subpackage Template
   7   */
   8  
   9  /**
  10   * Display the permalink for the current post.
  11   *
  12   * @since 1.2.0
  13   * @uses apply_filters() Calls 'the_permalink' filter on the permalink string.
  14   */
  15  function the_permalink() {
  16      echo apply_filters('the_permalink', get_permalink());
  17  }
  18  
  19  /**
  20   * Retrieve trailing slash string, if blog set for adding trailing slashes.
  21   *
  22   * Conditionally adds a trailing slash if the permalink structure has a trailing
  23   * slash, strips the trailing slash if not. The string is passed through the
  24   * 'user_trailingslashit' filter. Will remove trailing slash from string, if
  25   * blog is not set to have them.
  26   *
  27   * @since 2.2.0
  28   * @uses $wp_rewrite
  29   *
  30   * @param string $string URL with or without a trailing slash.
  31   * @param string $type_of_url The type of URL being considered (e.g. single, category, etc) for use in the filter.
  32   * @return string
  33   */
  34  function user_trailingslashit($string, $type_of_url = '') {
  35      global $wp_rewrite;
  36      if ( $wp_rewrite->use_trailing_slashes )
  37          $string = trailingslashit($string);
  38      else
  39          $string = untrailingslashit($string);
  40  
  41      // Note that $type_of_url can be one of following:
  42      // single, single_trackback, single_feed, single_paged, feed, category, page, year, month, day, paged, post_type_archive
  43      $string = apply_filters('user_trailingslashit', $string, $type_of_url);
  44      return $string;
  45  }
  46  
  47  /**
  48   * Display permalink anchor for current post.
  49   *
  50   * The permalink mode title will use the post title for the 'a' element 'id'
  51   * attribute. The id mode uses 'post-' with the post ID for the 'id' attribute.
  52   *
  53   * @since 0.71
  54   *
  55   * @param string $mode Permalink mode can be either 'title', 'id', or default, which is 'id'.
  56   */
  57  function permalink_anchor($mode = 'id') {
  58      global $post;
  59      switch ( strtolower($mode) ) {
  60          case 'title':
  61              $title = sanitize_title($post->post_title) . '-' . $post->ID;
  62              echo '<a id="'.$title.'"></a>';
  63              break;
  64          case 'id':
  65          default:
  66              echo '<a id="post-' . $post->ID . '"></a>';
  67              break;
  68      }
  69  }
  70  
  71  /**
  72   * Retrieve full permalink for current post or post ID.
  73   *
  74   * @since 1.0.0
  75   *
  76   * @param int $id Optional. Post ID.
  77   * @param bool $leavename Optional, defaults to false. Whether to keep post name or page name.
  78   * @return string
  79   */
  80  function get_permalink($id = 0, $leavename = false) {
  81      $rewritecode = array(
  82          '%year%',
  83          '%monthnum%',
  84          '%day%',
  85          '%hour%',
  86          '%minute%',
  87          '%second%',
  88          $leavename? '' : '%postname%',
  89          '%post_id%',
  90          '%category%',
  91          '%author%',
  92          $leavename? '' : '%pagename%',
  93      );
  94  
  95      if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter ) {
  96          $post = $id;
  97          $sample = true;
  98      } else {
  99          $post = &get_post($id);
 100          $sample = false;
 101      }
 102  
 103      if ( empty($post->ID) )
 104          return false;
 105  
 106      if ( $post->post_type == 'page' )
 107          return get_page_link($post->ID, $leavename, $sample);
 108      elseif ( $post->post_type == 'attachment' )
 109          return get_attachment_link($post->ID);
 110      elseif ( in_array($post->post_type, get_post_types( array('_builtin' => false) ) ) )
 111          return get_post_permalink($post->ID, $leavename, $sample);
 112  
 113      $permalink = get_option('permalink_structure');
 114  
 115      $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
 116  
 117      if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
 118          $unixtime = strtotime($post->post_date);
 119  
 120          $category = '';
 121          if ( strpos($permalink, '%category%') !== false ) {
 122              $cats = get_the_category($post->ID);
 123              if ( $cats ) {
 124                  usort($cats, '_usort_terms_by_ID'); // order by ID
 125                  $category = $cats[0]->slug;
 126                  if ( $parent = $cats[0]->parent )
 127                      $category = get_category_parents($parent, false, '/', true) . $category;
 128              }
 129              // show default category in permalinks, without
 130              // having to assign it explicitly
 131              if ( empty($category) ) {
 132                  $default_category = get_category( get_option( 'default_category' ) );
 133                  $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
 134              }
 135          }
 136  
 137          $author = '';
 138          if ( strpos($permalink, '%author%') !== false ) {
 139              $authordata = get_userdata($post->post_author);
 140              $author = $authordata->user_nicename;
 141          }
 142  
 143          $date = explode(" ",date('Y m d H i s', $unixtime));
 144          $rewritereplace =
 145          array(
 146              $date[0],
 147              $date[1],
 148              $date[2],
 149              $date[3],
 150              $date[4],
 151              $date[5],
 152              $post->post_name,
 153              $post->ID,
 154              $category,
 155              $author,
 156              $post->post_name,
 157          );
 158          $permalink = home_url( str_replace($rewritecode, $rewritereplace, $permalink) );
 159          $permalink = user_trailingslashit($permalink, 'single');
 160      } else { // if they're not using the fancy permalink option
 161          $permalink = home_url('?p=' . $post->ID);
 162      }
 163      return apply_filters('post_link', $permalink, $post, $leavename);
 164  }
 165  
 166  /**
 167   * Retrieve the permalink for a post with a custom post type.
 168   *
 169   * @since 3.0.0
 170   *
 171   * @param int $id Optional. Post ID.
 172   * @param bool $leavename Optional, defaults to false. Whether to keep post name.
 173   * @param bool $sample Optional, defaults to false. Is it a sample permalink.
 174   * @return string
 175   */
 176  function get_post_permalink( $id = 0, $leavename = false, $sample = false ) {
 177      global $wp_rewrite;
 178  
 179      $post = &get_post($id);
 180  
 181      if ( is_wp_error( $post ) )
 182          return $post;
 183  
 184      $post_link = $wp_rewrite->get_extra_permastruct($post->post_type);
 185  
 186      $slug = $post->post_name;
 187  
 188      $draft_or_pending = isset($post->post_status) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
 189  
 190      $post_type = get_post_type_object($post->post_type);
 191  
 192      if ( !empty($post_link) && ( !$draft_or_pending || $sample ) ) {
 193          if ( ! $leavename ) {
 194              if ( $post_type->hierarchical )
 195                  $slug = get_page_uri($id);
 196              $post_link = str_replace("%$post->post_type%", $slug, $post_link);
 197          }
 198          $post_link = home_url( user_trailingslashit($post_link) );
 199      } else {
 200          if ( $post_type->query_var && ( isset($post->post_status) && !$draft_or_pending ) )
 201              $post_link = add_query_arg($post_type->query_var, $slug, '');
 202          else
 203              $post_link = add_query_arg(array('post_type' => $post->post_type, 'p' => $post->ID), '');
 204          $post_link = home_url($post_link);
 205      }
 206  
 207      return apply_filters('post_type_link', $post_link, $post, $leavename, $sample);
 208  }
 209  
 210  /**
 211   * Retrieve permalink from post ID.
 212   *
 213   * @since 1.0.0
 214   *
 215   * @param int $post_id Optional. Post ID.
 216   * @param mixed $deprecated Not used.
 217   * @return string
 218   */
 219  function post_permalink( $post_id = 0, $deprecated = '' ) {
 220      if ( !empty( $deprecated ) )
 221          _deprecated_argument( __FUNCTION__, '1.3' );
 222  
 223      return get_permalink($post_id);
 224  }
 225  
 226  /**
 227   * Retrieve the permalink for current page or page ID.
 228   *
 229   * Respects page_on_front. Use this one.
 230   *
 231   * @since 1.5.0
 232   *
 233   * @param int $id Optional. Post ID.
 234   * @param bool $leavename Optional, defaults to false. Whether to keep page name.
 235   * @param bool $sample Optional, defaults to false. Is it a sample permalink.
 236   * @return string
 237   */
 238  function get_page_link( $id = false, $leavename = false, $sample = false ) {
 239      global $post;
 240  
 241      $id = (int) $id;
 242      if ( !$id )
 243          $id = (int) $post->ID;
 244  
 245      if ( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') )
 246          $link = home_url('/');
 247      else
 248          $link = _get_page_link( $id , $leavename, $sample );
 249  
 250      return apply_filters('page_link', $link, $id, $sample);
 251  }
 252  
 253  /**
 254   * Retrieve the page permalink.
 255   *
 256   * Ignores page_on_front. Internal use only.
 257   *
 258   * @since 2.1.0
 259   * @access private
 260   *
 261   * @param int $id Optional. Post ID.
 262   * @param bool $leavename Optional. Leave name.
 263   * @param bool $sample Optional. Sample permalink.
 264   * @return string
 265   */
 266  function _get_page_link( $id = false, $leavename = false, $sample = false ) {
 267      global $post, $wp_rewrite;
 268  
 269      if ( !$id )
 270          $id = (int) $post->ID;
 271      else
 272          $post = &get_post($id);
 273  
 274      $draft_or_pending = in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
 275  
 276      $link = $wp_rewrite->get_page_permastruct();
 277  
 278      if ( !empty($link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) {
 279          if ( ! $leavename ) {
 280              $link = str_replace('%pagename%', get_page_uri($id), $link);
 281          }
 282  
 283          $link = home_url($link);
 284          $link = user_trailingslashit($link, 'page');
 285      } else {
 286          $link = home_url("?page_id=$id");
 287      }
 288  
 289      return apply_filters( '_get_page_link', $link, $id );
 290  }
 291  
 292  /**
 293   * Retrieve permalink for attachment.
 294   *
 295   * This can be used in the WordPress Loop or outside of it.
 296   *
 297   * @since 2.0.0
 298   *
 299   * @param int $id Optional. Post ID.
 300   * @return string
 301   */
 302  function get_attachment_link($id = false) {
 303      global $post, $wp_rewrite;
 304  
 305      $link = false;
 306  
 307      if ( ! $id)
 308          $id = (int) $post->ID;
 309  
 310      $object = get_post($id);
 311      if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) {
 312          $parent = get_post($object->post_parent);
 313          if ( 'page' == $parent->post_type )
 314              $parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front
 315          else
 316              $parentlink = get_permalink( $object->post_parent );
 317  
 318          if ( is_numeric($object->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') )
 319              $name = 'attachment/' . $object->post_name; // <permalink>/<int>/ is paged so we use the explicit attachment marker
 320          else
 321              $name = $object->post_name;
 322  
 323          if ( strpos($parentlink, '?') === false )
 324              $link = user_trailingslashit( trailingslashit($parentlink) . $name );
 325      }
 326  
 327      if ( ! $link )
 328          $link = home_url( "/?attachment_id=$id" );
 329  
 330      return apply_filters('attachment_link', $link, $id);
 331  }
 332  
 333  /**
 334   * Retrieve the permalink for the year archives.
 335   *
 336   * @since 1.5.0
 337   *
 338   * @param int|bool $year False for current year or year for permalink.
 339   * @return string
 340   */
 341  function get_year_link($year) {
 342      global $wp_rewrite;
 343      if ( !$year )
 344          $year = gmdate('Y', current_time('timestamp'));
 345      $yearlink = $wp_rewrite->get_year_permastruct();
 346      if ( !empty($yearlink) ) {
 347          $yearlink = str_replace('%year%', $year, $yearlink);
 348          return apply_filters('year_link', home_url( user_trailingslashit($yearlink, 'year') ), $year);
 349      } else {
 350          return apply_filters('year_link', home_url('?m=' . $year), $year);
 351      }
 352  }
 353  
 354  /**
 355   * Retrieve the permalink for the month archives with year.
 356   *
 357   * @since 1.0.0
 358   *
 359   * @param bool|int $year False for current year. Integer of year.
 360   * @param bool|int $month False for current month. Integer of month.
 361   * @return string
 362   */
 363  function get_month_link($year, $month) {
 364      global $wp_rewrite;
 365      if ( !$year )
 366          $year = gmdate('Y', current_time('timestamp'));
 367      if ( !$month )
 368          $month = gmdate('m', current_time('timestamp'));
 369      $monthlink = $wp_rewrite->get_month_permastruct();
 370      if ( !empty($monthlink) ) {
 371          $monthlink = str_replace('%year%', $year, $monthlink);
 372          $monthlink = str_replace('%monthnum%', zeroise(intval($month), 2), $monthlink);
 373          return apply_filters('month_link', home_url( user_trailingslashit($monthlink, 'month') ), $year, $month);
 374      } else {
 375          return apply_filters('month_link', home_url( '?m=' . $year . zeroise($month, 2) ), $year, $month);
 376      }
 377  }
 378  
 379  /**
 380   * Retrieve the permalink for the day archives with year and month.
 381   *
 382   * @since 1.0.0
 383   *
 384   * @param bool|int $year False for current year. Integer of year.
 385   * @param bool|int $month False for current month. Integer of month.
 386   * @param bool|int $day False for current day. Integer of day.
 387   * @return string
 388   */
 389  function get_day_link($year, $month, $day) {
 390      global $wp_rewrite;
 391      if ( !$year )
 392          $year = gmdate('Y', current_time('timestamp'));
 393      if ( !$month )
 394          $month = gmdate('m', current_time('timestamp'));
 395      if ( !$day )
 396          $day = gmdate('j', current_time('timestamp'));
 397  
 398      $daylink = $wp_rewrite->get_day_permastruct();
 399      if ( !empty($daylink) ) {
 400          $daylink = str_replace('%year%', $year, $daylink);
 401          $daylink = str_replace('%monthnum%', zeroise(intval($month), 2), $daylink);
 402          $daylink = str_replace('%day%', zeroise(intval($day), 2), $daylink);
 403          return apply_filters('day_link', home_url( user_trailingslashit($daylink, 'day') ), $year, $month, $day);
 404      } else {
 405          return apply_filters('day_link', home_url( '?m=' . $year . zeroise($month, 2) . zeroise($day, 2) ), $year, $month, $day);
 406      }
 407  }
 408  
 409  /**
 410   * Display the permalink for the feed type.
 411   *
 412   * @since 3.0.0
 413   *
 414   * @param string $anchor The link's anchor text.
 415   * @param string $feed Optional, defaults to default feed. Feed type.
 416   */
 417  function the_feed_link( $anchor, $feed = '' ) {
 418      $link = '<a href="' . esc_url( get_feed_link( $feed ) ) . '">' . $anchor . '</a>';
 419      echo apply_filters( 'the_feed_link', $link, $feed );
 420  }
 421  
 422  /**
 423   * Retrieve the permalink for the feed type.
 424   *
 425   * @since 1.5.0
 426   *
 427   * @param string $feed Optional, defaults to default feed. Feed type.
 428   * @return string
 429   */
 430  function get_feed_link($feed = '') {
 431      global $wp_rewrite;
 432  
 433      $permalink = $wp_rewrite->get_feed_permastruct();
 434      if ( '' != $permalink ) {
 435          if ( false !== strpos($feed, 'comments_') ) {
 436              $feed = str_replace('comments_', '', $feed);
 437              $permalink = $wp_rewrite->get_comment_feed_permastruct();
 438          }
 439  
 440          if ( get_default_feed() == $feed )
 441              $feed = '';
 442  
 443          $permalink = str_replace('%feed%', $feed, $permalink);
 444          $permalink = preg_replace('#/+#', '/', "/$permalink");
 445          $output =  home_url( user_trailingslashit($permalink, 'feed') );
 446      } else {
 447          if ( empty($feed) )
 448              $feed = get_default_feed();
 449  
 450          if ( false !== strpos($feed, 'comments_') )
 451              $feed = str_replace('comments_', 'comments-', $feed);
 452  
 453          $output = home_url("?feed={$feed}");
 454      }
 455  
 456      return apply_filters('feed_link', $output, $feed);
 457  }
 458  
 459  /**
 460   * Retrieve the permalink for the post comments feed.
 461   *
 462   * @since 2.2.0
 463   *
 464   * @param int $post_id Optional. Post ID.
 465   * @param string $feed Optional. Feed type.
 466   * @return string
 467   */
 468  function get_post_comments_feed_link($post_id = 0, $feed = '') {
 469      $post_id = absint( $post_id );
 470  
 471      if ( ! $post_id )
 472          $post_id = get_the_ID();
 473  
 474      if ( empty( $feed ) )
 475          $feed = get_default_feed();
 476  
 477      if ( '' != get_option('permalink_structure') ) {
 478          if ( 'page' == get_option('show_on_front') && $post_id == get_option('page_on_front') )
 479              $url = _get_page_link( $post_id );
 480          else
 481              $url = get_permalink($post_id);
 482  
 483          $url = trailingslashit($url) . 'feed';
 484          if ( $feed != get_default_feed() )
 485              $url .= "/$feed";
 486          $url = user_trailingslashit($url, 'single_feed');
 487      } else {
 488          $type = get_post_field('post_type', $post_id);
 489          if ( 'page' == $type )
 490              $url = home_url("?feed=$feed&amp;page_id=$post_id");
 491          else
 492              $url = home_url("?feed=$feed&amp;p=$post_id");
 493      }
 494  
 495      return apply_filters('post_comments_feed_link', $url);
 496  }
 497  
 498  /**
 499   * Display the comment feed link for a post.
 500   *
 501   * Prints out the comment feed link for a post. Link text is placed in the
 502   * anchor. If no link text is specified, default text is used. If no post ID is
 503   * specified, the current post is used.
 504   *
 505   * @package WordPress
 506   * @subpackage Feed
 507   * @since 2.5.0
 508   *
 509   * @param string $link_text Descriptive text.
 510   * @param int $post_id Optional post ID. Default to current post.
 511   * @param string $feed Optional. Feed format.
 512   * @return string Link to the comment feed for the current post.
 513  */
 514  function post_comments_feed_link( $link_text = '', $post_id = '', $feed = '' ) {
 515      $url = get_post_comments_feed_link($post_id, $feed);
 516      if ( empty($link_text) )
 517          $link_text = __('Comments Feed');
 518  
 519      echo apply_filters( 'post_comments_feed_link_html', "<a href='$url'>$link_text</a>", $post_id, $feed );
 520  }
 521  
 522  /**
 523   * Retrieve the feed link for a given author.
 524   *
 525   * Returns a link to the feed for all posts by a given author. A specific feed
 526   * can be requested or left blank to get the default feed.
 527   *
 528   * @package WordPress
 529   * @subpackage Feed
 530   * @since 2.5.0
 531   *
 532   * @param int $author_id ID of an author.
 533   * @param string $feed Optional. Feed type.
 534   * @return string Link to the feed for the author specified by $author_id.
 535  */
 536  function get_author_feed_link( $author_id, $feed = '' ) {
 537      $author_id = (int) $author_id;
 538      $permalink_structure = get_option('permalink_structure');
 539  
 540      if ( empty($feed) )
 541          $feed = get_default_feed();
 542  
 543      if ( '' == $permalink_structure ) {
 544          $link = home_url("?feed=$feed&amp;author=" . $author_id);
 545      } else {
 546          $link = get_author_posts_url($author_id);
 547          if ( $feed == get_default_feed() )
 548              $feed_link = 'feed';
 549          else
 550              $feed_link = "feed/$feed";
 551  
 552          $link = trailingslashit($link) . user_trailingslashit($feed_link, 'feed');
 553      }
 554  
 555      $link = apply_filters('author_feed_link', $link, $feed);
 556  
 557      return $link;
 558  }
 559  
 560  /**
 561   * Retrieve the feed link for a category.
 562   *
 563   * Returns a link to the feed for all posts in a given category. A specific feed
 564   * can be requested or left blank to get the default feed.
 565   *
 566   * @package WordPress
 567   * @subpackage Feed
 568   * @since 2.5.0
 569   *
 570   * @param int $cat_id ID of a category.
 571   * @param string $feed Optional. Feed type.
 572   * @return string Link to the feed for the category specified by $cat_id.
 573  */
 574  function get_category_feed_link($cat_id, $feed = '') {
 575      return get_term_feed_link($cat_id, 'category', $feed);
 576  }
 577  
 578  /**
 579   * Retrieve the feed link for a term.
 580   *
 581   * Returns a link to the feed for all posts in a given term. A specific feed
 582   * can be requested or left blank to get the default feed.
 583   *
 584   * @since 3.0
 585   *
 586   * @param int $term_id ID of a category.
 587   * @param string $taxonomy Optional. Taxonomy of $term_id
 588   * @param string $feed Optional. Feed type.
 589   * @return string Link to the feed for the term specified by $term_id and $taxonomy.
 590  */
 591  function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) {
 592      global $wp_rewrite;
 593  
 594      $term_id = ( int ) $term_id;
 595  
 596      $term = get_term( $term_id, $taxonomy  );
 597  
 598      if ( empty( $term ) || is_wp_error( $term ) )
 599          return false;
 600  
 601      if ( empty( $feed ) )
 602          $feed = get_default_feed();
 603  
 604      $permalink_structure = get_option( 'permalink_structure' );
 605  
 606      if ( '' == $permalink_structure ) {
 607          if ( 'category' == $taxonomy ) {
 608              $link = home_url("?feed=$feed&amp;cat=$term_id");
 609          }
 610          elseif ( 'post_tag' == $taxonomy ) {
 611              $link = home_url("?feed=$feed&amp;tag=$term->slug");
 612          } else {
 613              $t = get_taxonomy( $taxonomy );
 614              $link = home_url("?feed=$feed&amp;$t->query_var=$term->slug");
 615          }
 616      } else {
 617          $link = get_term_link( $term_id, $term->taxonomy );
 618          if ( $feed == get_default_feed() )
 619              $feed_link = 'feed';
 620          else
 621              $feed_link = "feed/$feed";
 622  
 623          $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' );
 624      }
 625  
 626      if ( 'category' == $taxonomy )
 627          $link = apply_filters( 'category_feed_link', $link, $feed );
 628      elseif ( 'post_tag' == $taxonomy )
 629          $link = apply_filters( 'category_feed_link', $link, $feed );
 630      else
 631          $link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy );
 632  
 633      return $link;
 634  }
 635  
 636  /**
 637   * Retrieve permalink for feed of tag.
 638   *
 639   * @since 2.3.0
 640   *
 641   * @param int $tag_id Tag ID.
 642   * @param string $feed Optional. Feed type.
 643   * @return string
 644   */
 645  function get_tag_feed_link($tag_id, $feed = '') {
 646      return get_term_feed_link($tag_id, 'post_tag', $feed);
 647  }
 648  
 649  /**
 650   * Retrieve edit tag link.
 651   *
 652   * @since 2.7.0
 653   *
 654   * @param int $tag_id Tag ID
 655   * @param string $taxonomy Taxonomy
 656   * @return string
 657   */
 658  function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) {
 659      return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag_id, $taxonomy ) );
 660  }
 661  
 662  /**
 663   * Display or retrieve edit tag link with formatting.
 664   *
 665   * @since 2.7.0
 666   *
 667   * @param string $link Optional. Anchor text.
 668   * @param string $before Optional. Display before edit link.
 669   * @param string $after Optional. Display after edit link.
 670   * @param int|object $tag Tag object or ID
 671   * @return string HTML content.
 672   */
 673  function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) {
 674      $link = edit_term_link( $link, '', '', false, $tag );
 675      echo $before . apply_filters( 'edit_tag_link', $link ) . $after;
 676  }
 677  
 678  /**
 679   * Retrieve edit term url.
 680   *
 681   * @since 3.1.0
 682   *
 683   * @param int $term_id Term ID
 684   * @param string $taxonomy Taxonomy
 685   * @param string $object_type The object type
 686   * @return string
 687   */
 688  function get_edit_term_link( $term_id, $taxonomy, $object_type = '' ) {
 689      $tax = get_taxonomy( $taxonomy );
 690      if ( !current_user_can( $tax->cap->edit_terms ) )
 691          return;
 692  
 693      $term = get_term( $term_id, $taxonomy );
 694  
 695      $args = array(
 696          'action' => 'edit',
 697          'taxonomy' => $taxonomy,
 698          'tag_ID' => $term->term_id,
 699      );
 700  
 701      if ( $object_type )
 702          $args['post_type'] = $object_type;
 703  
 704      $location = add_query_arg( $args, admin_url( 'edit-tags.php' ) );
 705  
 706      return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type );
 707  }
 708  
 709  /**
 710   * Display or retrieve edit term link with formatting.
 711   *
 712   * @since 3.1.0
 713   *
 714   * @param string $link Optional. Anchor text.
 715   * @param string $before Optional. Display before edit link.
 716   * @param string $after Optional. Display after edit link.
 717   * @param object $term Term object
 718   * @return string HTML content.
 719   */
 720  function edit_term_link( $link = '', $before = '', $after = '', $term = null, $echo = true ) {
 721      if ( is_null( $term ) ) {
 722          $term = get_queried_object();
 723      }
 724  
 725      $tax = get_taxonomy( $term->taxonomy );
 726      if ( !current_user_can($tax->cap->edit_terms) )
 727          return;
 728  
 729      if ( empty( $link ) )
 730          $link = __('Edit This');
 731  
 732      $link = '<a href="' . get_edit_term_link( $term->term_id, $term->taxonomy ) . '" title="' . $link . '">' . $link . '</a>';
 733      $link = $before . apply_filters( 'edit_term_link', $link, $term->term_id ) . $after;
 734  
 735      if ( $echo )
 736          echo $link;
 737      else
 738          return $link;
 739  }
 740  
 741  /**
 742  * Retrieve permalink for search.
 743  *
 744  * @since  3.0.0
 745  * @param string $query Optional. The query string to use. If empty the current query is used.
 746  * @return string
 747  */
 748  function get_search_link( $query = '' ) {
 749      global $wp_rewrite;
 750  
 751      if ( empty($query) )
 752          $search = get_search_query( false );
 753      else
 754          $search = stripslashes($query);
 755  
 756      $permastruct = $wp_rewrite->get_search_permastruct();
 757  
 758      if ( empty( $permastruct ) ) {
 759          $link = home_url('?s=' . urlencode($search) );
 760      } else {
 761          $search = urlencode($search);
 762          $search = str_replace('%2F', '/', $search); // %2F(/) is not valid within a URL, send it unencoded.
 763          $link = str_replace( '%search%', $search, $permastruct );
 764          $link = home_url( user_trailingslashit( $link, 'search' ) );
 765      }
 766  
 767      return apply_filters( 'search_link', $link, $search );
 768  }
 769  
 770  /**
 771   * Retrieve the permalink for the feed of the search results.
 772   *
 773   * @since 2.5.0
 774   *
 775   * @param string $search_query Optional. Search query.
 776   * @param string $feed Optional. Feed type.
 777   * @return string
 778   */
 779  function get_search_feed_link($search_query = '', $feed = '') {
 780      global $wp_rewrite;
 781      $link = get_search_link($search_query);
 782  
 783      if ( empty($feed) )
 784          $feed = get_default_feed();
 785  
 786      $permastruct = $wp_rewrite->get_search_permastruct();
 787  
 788      if ( empty($permastruct) ) {
 789          $link = add_query_arg('feed', $feed, $link);
 790      } else {
 791          $link = trailingslashit($link);
 792          $link .= "feed/$feed/";
 793      }
 794  
 795      $link = apply_filters('search_feed_link', $link, $feed, 'posts');
 796  
 797      return $link;
 798  }
 799  
 800  /**
 801   * Retrieve the permalink for the comments feed of the search results.
 802   *
 803   * @since 2.5.0
 804   *
 805   * @param string $search_query Optional. Search query.
 806   * @param string $feed Optional. Feed type.
 807   * @return string
 808   */
 809  function get_search_comments_feed_link($search_query = '', $feed = '') {
 810      global $wp_rewrite;
 811  
 812      if ( empty($feed) )
 813          $feed = get_default_feed();
 814  
 815      $link = get_search_feed_link($search_query, $feed);
 816  
 817      $permastruct = $wp_rewrite->get_search_permastruct();
 818  
 819      if ( empty($permastruct) )
 820          $link = add_query_arg('feed', 'comments-' . $feed, $link);
 821      else
 822          $link = add_query_arg('withcomments', 1, $link);
 823  
 824      $link = apply_filters('search_feed_link', $link, $feed, 'comments');
 825  
 826      return $link;
 827  }
 828  
 829  /**
 830   * Retrieve the permalink for a post type archive.
 831   *
 832   * @since 3.1.0
 833   *
 834   * @param string $post_type Post type
 835   * @return string
 836   */
 837  function get_post_type_archive_link( $post_type ) {
 838      global $wp_rewrite;
 839      if ( ! $post_type_obj = get_post_type_object( $post_type ) )
 840          return false;
 841  
 842      if ( ! $post_type_obj->has_archive )
 843          return false;
 844  
 845      if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) ) {
 846          $struct = ( true === $post_type_obj->has_archive ) ? $post_type_obj->rewrite['slug'] : $post_type_obj->has_archive;
 847          if ( $post_type_obj->rewrite['with_front'] )
 848              $struct = $wp_rewrite->front . $struct;
 849          else
 850              $struct = $wp_rewrite->root . $struct;
 851          $link = home_url( user_trailingslashit( $struct, 'post_type_archive' ) );
 852      } else {
 853          $link = home_url( '?post_type=' . $post_type );
 854      }
 855  
 856      return apply_filters( 'post_type_archive_link', $link, $post_type );
 857  }
 858  
 859  /**
 860   * Retrieve the permalink for a post type archive feed.
 861   *
 862   * @since 3.1.0
 863   *
 864   * @param string $post_type Post type
 865   * @param string $feed Optional. Feed type
 866   * @return string
 867   */
 868  function get_post_type_archive_feed_link( $post_type, $feed = '' ) {
 869      $default_feed = get_default_feed();
 870      if ( empty( $feed ) )
 871          $feed = $default_feed;
 872  
 873      if ( ! $link = get_post_type_archive_link( $post_type ) )
 874          return false;
 875      $post_type_obj = get_post_type_object( $post_type );
 876      if ( $post_type_obj->rewrite['feeds'] && get_option( 'permalink_structure' ) ) {
 877          $link = trailingslashit($link);
 878          $link .= 'feed/';
 879          if ( $feed != $default_feed )
 880              $link .= "$feed/";
 881      } else {
 882          $link = add_query_arg( 'feed', $feed, $link );
 883      }
 884  
 885      return apply_filters( 'post_type_archive_feed_link', $link, $feed );
 886  }
 887  
 888  /**
 889   * Retrieve edit posts link for post.
 890   *
 891   * Can be used within the WordPress loop or outside of it. Can be used with
 892   * pages, posts, attachments, and revisions.
 893   *
 894   * @since 2.3.0
 895   *
 896   * @param int $id Optional. Post ID.
 897   * @param string $context Optional, defaults to display. How to write the '&', defaults to '&amp;'.
 898   * @return string
 899   */
 900  function get_edit_post_link( $id = 0, $context = 'display' ) {
 901      if ( !$post = &get_post( $id ) )
 902          return;
 903  
 904      if ( 'display' == $context )
 905          $action = '&amp;action=edit';
 906      else
 907          $action = '&action=edit';
 908  
 909      $post_type_object = get_post_type_object( $post->post_type );
 910      if ( !$post_type_object )
 911          return;
 912  
 913      if ( !current_user_can( $post_type_object->cap->edit_post, $post->ID ) )
 914          return;
 915  
 916      return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context );
 917  }
 918  
 919  /**
 920   * Display edit post link for post.
 921   *
 922   * @since 1.0.0
 923   *
 924   * @param string $link Optional. Anchor text.
 925   * @param string $before Optional. Display before edit link.
 926   * @param string $after Optional. Display after edit link.
 927   * @param int $id Optional. Post ID.
 928   */
 929  function edit_post_link( $link = null, $before = '', $after = '', $id = 0 ) {
 930      if ( !$post = &get_post( $id ) )
 931          return;
 932  
 933      if ( !$url = get_edit_post_link( $post->ID ) )
 934          return;
 935  
 936      if ( null === $link )
 937          $link = __('Edit This');
 938  
 939      $post_type_obj = get_post_type_object( $post->post_type );
 940      $link = '<a class="post-edit-link" href="' . $url . '" title="' . esc_attr( $post_type_obj->labels->edit_item ) . '">' . $link . '</a>';
 941      echo $before . apply_filters( 'edit_post_link', $link, $post->ID ) . $after;
 942  }
 943  
 944  /**
 945   * Retrieve delete posts link for post.
 946   *
 947   * Can be used within the WordPress loop or outside of it, with any post type.
 948   *
 949   * @since 2.9.0
 950   *
 951   * @param int $id Optional. Post ID.
 952   * @param string $deprecated Not used.
 953   * @param bool $force_delete Whether to bypass trash and force deletion. Default is false.
 954   * @return string
 955   */
 956  function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false ) {
 957      if ( ! empty( $deprecated ) )
 958          _deprecated_argument( __FUNCTION__, '3.0' );
 959  
 960      if ( !$post = &get_post( $id ) )
 961          return;
 962  
 963      $post_type_object = get_post_type_object( $post->post_type );
 964      if ( !$post_type_object )
 965          return;
 966  
 967      if ( !current_user_can( $post_type_object->cap->delete_post, $post->ID ) )
 968          return;
 969  
 970      $action = ( $force_delete || !EMPTY_TRASH_DAYS ) ? 'delete' : 'trash';
 971  
 972      $delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) );
 973  
 974      return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-{$post->post_type}_{$post->ID}" ), $post->ID, $force_delete );
 975  }
 976  
 977  /**
 978   * Retrieve edit comment link.
 979   *
 980   * @since 2.3.0
 981   *
 982   * @param int $comment_id Optional. Comment ID.
 983   * @return string
 984   */
 985  function get_edit_comment_link( $comment_id = 0 ) {
 986      $comment = &get_comment( $comment_id );
 987  
 988      if ( !current_user_can( 'edit_comment', $comment->comment_ID ) )
 989          return;
 990  
 991      $location = admin_url('comment.php?action=editcomment&amp;c=') . $comment->comment_ID;
 992      return apply_filters( 'get_edit_comment_link', $location );
 993  }
 994  
 995  /**
 996   * Display or retrieve edit comment link with formatting.
 997   *
 998   * @since 1.0.0
 999   *
1000   * @param string $link Optional. Anchor text.
1001   * @param string $before Optional. Display before edit link.
1002   * @param string $after Optional. Display after edit link.
1003   * @return string|null HTML content, if $echo is set to false.
1004   */
1005  function edit_comment_link( $link = null, $before = '', $after = '' ) {
1006      global $comment;
1007  
1008      if ( !current_user_can( 'edit_comment', $comment->comment_ID ) )
1009          return;
1010  
1011      if ( null === $link )
1012          $link = __('Edit This');
1013  
1014      $link = '<a class="comment-edit-link" href="' . get_edit_comment_link( $comment->comment_ID ) . '" title="' . esc_attr__( 'Edit comment' ) . '">' . $link . '</a>';
1015      echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID ) . $after;
1016  }
1017  
1018  /**
1019   * Display edit bookmark (literally a URL external to blog) link.
1020   *
1021   * @since 2.7.0
1022   *
1023   * @param int $link Optional. Bookmark ID.
1024   * @return string
1025   */
1026  function get_edit_bookmark_link( $link = 0 ) {
1027      $link = get_bookmark( $link );
1028  
1029      if ( !current_user_can('manage_links') )
1030          return;
1031  
1032      $location = admin_url('link.php?action=edit&amp;link_id=') . $link->link_id;
1033      return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id );
1034  }
1035  
1036  /**
1037   * Display edit bookmark (literally a URL external to blog) link anchor content.
1038   *
1039   * @since 2.7.0
1040   *
1041   * @param string $link Optional. Anchor text.
1042   * @param string $before Optional. Display before edit link.
1043   * @param string $after Optional. Display after edit link.
1044   * @param int $bookmark Optional. Bookmark ID.
1045   */
1046  function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) {
1047      $bookmark = get_bookmark($bookmark);
1048  
1049      if ( !current_user_can('manage_links') )
1050          return;
1051  
1052      if ( empty($link) )
1053          $link = __('Edit This');
1054  
1055      $link = '<a href="' . get_edit_bookmark_link( $bookmark ) . '" title="' . esc_attr__( 'Edit Link' ) . '">' . $link . '</a>';
1056      echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after;
1057  }
1058  
1059  // Navigation links
1060  
1061  /**
1062   * Retrieve previous post that is adjacent to current post.
1063   *
1064   * @since 1.5.0
1065   *
1066   * @param bool $in_same_cat Optional. Whether post should be in a same category.
1067   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1068   * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
1069   */
1070  function get_previous_post($in_same_cat = false, $excluded_categories = '') {
1071      return get_adjacent_post($in_same_cat, $excluded_categories);
1072  }
1073  
1074  /**
1075   * Retrieve next post that is adjacent to current post.
1076   *
1077   * @since 1.5.0
1078   *
1079   * @param bool $in_same_cat Optional. Whether post should be in a same category.
1080   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1081   * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
1082   */
1083  function get_next_post($in_same_cat = false, $excluded_categories = '') {
1084      return get_adjacent_post($in_same_cat, $excluded_categories, false);
1085  }
1086  
1087  /**
1088   * Retrieve adjacent post.
1089   *
1090   * Can either be next or previous post.
1091   *
1092   * @since 2.5.0
1093   *
1094   * @param bool $in_same_cat Optional. Whether post should be in a same category.
1095   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1096   * @param bool $previous Optional. Whether to retrieve previous post.
1097   * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
1098   */
1099  function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $previous = true ) {
1100      global $post, $wpdb;
1101  
1102      if ( empty( $post ) )
1103          return null;
1104  
1105      $current_post_date = $post->post_date;
1106  
1107      $join = '';
1108      $posts_in_ex_cats_sql = '';
1109      if ( $in_same_cat || ! empty( $excluded_categories ) ) {
1110          $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";
1111  
1112          if ( $in_same_cat ) {
1113              $cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids'));
1114              $join .= " AND tt.taxonomy = 'category' AND tt.term_id IN (" . implode(',', $cat_array) . ")";
1115          }
1116  
1117          $posts_in_ex_cats_sql = "AND tt.taxonomy = 'category'";
1118          if ( ! empty( $excluded_categories ) ) {
1119              if ( ! is_array( $excluded_categories ) ) {
1120                  // back-compat, $excluded_categories used to be IDs separated by " and "
1121                  if ( strpos( $excluded_categories, ' and ' ) !== false ) {
1122                      _deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded categories.' ), "'and'" ) );
1123                      $excluded_categories = explode( ' and ', $excluded_categories );
1124                  } else {
1125                      $excluded_categories = explode( ',', $excluded_categories );
1126                  }
1127              }
1128  
1129              $excluded_categories = array_map( 'intval', $excluded_categories );
1130  
1131              if ( ! empty( $cat_array ) ) {
1132                  $excluded_categories = array_diff($excluded_categories, $cat_array);
1133                  $posts_in_ex_cats_sql = '';
1134              }
1135  
1136              if ( !empty($excluded_categories) ) {
1137                  $posts_in_ex_cats_sql = " AND tt.taxonomy = 'category' AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')';
1138              }
1139          }
1140      }
1141  
1142      $adjacent = $previous ? 'previous' : 'next';
1143      $op = $previous ? '<' : '>';
1144      $order = $previous ? 'DESC' : 'ASC';
1145  
1146      $join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cat, $excluded_categories );
1147      $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_cats_sql", $current_post_date, $post->post_type), $in_same_cat, $excluded_categories );
1148      $sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );
1149  
1150      $query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort";
1151      $query_key = 'adjacent_post_' . md5($query);
1152      $result = wp_cache_get($query_key, 'counts');
1153      if ( false !== $result )
1154          return $result;
1155  
1156      $result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort");
1157      if ( null === $result )
1158          $result = '';
1159  
1160      wp_cache_set($query_key, $result, 'counts');
1161      return $result;
1162  }
1163  
1164  /**
1165   * Get adjacent post relational link.
1166   *
1167   * Can either be next or previous post relational link.
1168   *
1169   * @since 2.8.0
1170   *
1171   * @param string $title Optional. Link title format.
1172   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1173   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1174   * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
1175   * @return string
1176   */
1177  function get_adjacent_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $previous = true) {
1178      if ( $previous && is_attachment() && is_object( $GLOBALS['post'] ) )
1179          $post = & get_post($GLOBALS['post']->post_parent);
1180      else
1181          $post = get_adjacent_post($in_same_cat,$excluded_categories,$previous);
1182  
1183      if ( empty($post) )
1184          return;
1185  
1186      if ( empty($post->post_title) )
1187          $post->post_title = $previous ? __('Previous Post') : __('Next Post');
1188  
1189      $date = mysql2date(get_option('date_format'), $post->post_date);
1190  
1191      $title = str_replace('%title', $post->post_title, $title);
1192      $title = str_replace('%date', $date, $title);
1193      $title = apply_filters('the_title', $title, $post->ID);
1194  
1195      $link = $previous ? "<link rel='prev' title='" : "<link rel='next' title='";
1196      $link .= esc_attr( $title );
1197      $link .= "' href='" . get_permalink($post) . "' />\n";
1198  
1199      $adjacent = $previous ? 'previous' : 'next';
1200      return apply_filters( "{$adjacent}_post_rel_link", $link );
1201  }
1202  
1203  /**
1204   * Display relational links for the posts adjacent to the current post.
1205   *
1206   * @since 2.8.0
1207   *
1208   * @param string $title Optional. Link title format.
1209   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1210   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1211   */
1212  function adjacent_posts_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
1213      echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true);
1214      echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false);
1215  }
1216  
1217  /**
1218   * Display relational links for the posts adjacent to the current post for single post pages.
1219   *
1220   * This is meant to be attached to actions like 'wp_head'. Do not call this directly in plugins or theme templates.
1221   * @since 3.0.0
1222   *
1223   */
1224  function adjacent_posts_rel_link_wp_head() {
1225      if ( !is_singular() || is_attachment() )
1226          return;
1227      adjacent_posts_rel_link();
1228  }
1229  
1230  /**
1231   * Display relational link for the next post adjacent to the current post.
1232   *
1233   * @since 2.8.0
1234   *
1235   * @param string $title Optional. Link title format.
1236   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1237   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1238   */
1239  function next_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
1240      echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false);
1241  }
1242  
1243  /**
1244   * Display relational link for the previous post adjacent to the current post.
1245   *
1246   * @since 2.8.0
1247   *
1248   * @param string $title Optional. Link title format.
1249   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1250   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1251   */
1252  function prev_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
1253      echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true);
1254  }
1255  
1256  /**
1257   * Retrieve boundary post.
1258   *
1259   * Boundary being either the first or last post by publish date within the constraints specified
1260   * by $in_same_cat or $excluded_categories.
1261   *
1262   * @since 2.8.0
1263   *
1264   * @param bool $in_same_cat Optional. Whether returned post should be in a same category.
1265   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1266   * @param bool $start Optional. Whether to retrieve first or last post.
1267   * @return object
1268   */
1269  function get_boundary_post( $in_same_cat = false, $excluded_categories = '', $start = true ) {
1270      global $post;
1271  
1272      if ( empty($post) || ! is_single() || is_attachment() )
1273          return null;
1274  
1275      $cat_array = array();
1276      if( ! is_array( $excluded_categories ) )
1277          $excluded_categories = explode( ',', $excluded_categories );
1278  
1279      if ( $in_same_cat || ! empty( $excluded_categories ) ) {
1280          if ( $in_same_cat )
1281              $cat_array = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'ids' ) );
1282  
1283          if ( ! empty( $excluded_categories ) ) {
1284              $excluded_categories = array_map( 'intval', $excluded_categories );
1285              $excluded_categories = array_diff( $excluded_categories, $cat_array );
1286  
1287              $inverse_cats = array();
1288              foreach ( $excluded_categories as $excluded_category )
1289                  $inverse_cats[] = $excluded_category * -1;
1290              $excluded_categories = $inverse_cats;
1291          }
1292      }
1293  
1294      $categories = implode( ',', array_merge( $cat_array, $excluded_categories ) );
1295  
1296      $order = $start ? 'ASC' : 'DESC';
1297  
1298      return get_posts( array('numberposts' => 1, 'category' => $categories, 'order' => $order, 'update_post_term_cache' => false, 'update_post_meta_cache' => false) );
1299  }
1300  
1301  /**
1302   * Display previous post link that is adjacent to the current post.
1303   *
1304   * @since 1.5.0
1305   *
1306   * @param string $format Optional. Link anchor format.
1307   * @param string $link Optional. Link permalink format.
1308   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1309   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1310   */
1311  function previous_post_link($format='&laquo; %link', $link='%title', $in_same_cat = false, $excluded_categories = '') {
1312      adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, true);
1313  }
1314  
1315  /**
1316   * Display next post link that is adjacent to the current post.
1317   *
1318   * @since 1.5.0
1319   *
1320   * @param string $format Optional. Link anchor format.
1321   * @param string $link Optional. Link permalink format.
1322   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1323   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1324   */
1325  function next_post_link($format='%link &raquo;', $link='%title', $in_same_cat = false, $excluded_categories = '') {
1326      adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, false);
1327  }
1328  
1329  /**
1330   * Display adjacent post link.
1331   *
1332   * Can be either next post link or previous.
1333   *
1334   * @since 2.5.0
1335   *
1336   * @param string $format Link anchor format.
1337   * @param string $link Link permalink format.
1338   * @param bool $in_same_cat Optional. Whether link should be in a same category.
1339   * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
1340   * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
1341   */
1342  function adjacent_post_link($format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true) {
1343      if ( $previous && is_attachment() )
1344          $post = & get_post($GLOBALS['post']->post_parent);
1345      else
1346          $post = get_adjacent_post($in_same_cat, $excluded_categories, $previous);
1347  
1348      if ( !$post )
1349          return;
1350  
1351      $title = $post->post_title;
1352  
1353      if ( empty($post->post_title) )
1354          $title = $previous ? __('Previous Post') : __('Next Post');
1355  
1356      $title = apply_filters('the_title', $title, $post->ID);
1357      $date = mysql2date(get_option('date_format'), $post->post_date);
1358      $rel = $previous ? 'prev' : 'next';
1359  
1360      $string = '<a href="'.get_permalink($post).'" rel="'.$rel.'">';
1361      $link = str_replace('%title', $title, $link);
1362      $link = str_replace('%date', $date, $link);
1363      $link = $string . $link . '</a>';
1364  
1365      $format = str_replace('%link', $link, $format);
1366  
1367      $adjacent = $previous ? 'previous' : 'next';
1368      echo apply_filters( "{$adjacent}_post_link", $format, $link );
1369  }
1370  
1371  /**
1372   * Retrieve links for page numbers.
1373   *
1374   * @since 1.5.0
1375   *
1376   * @param int $pagenum Optional. Page ID.
1377   * @return string
1378   */
1379  function get_pagenum_link($pagenum = 1) {
1380      global $wp_rewrite;
1381  
1382      $pagenum = (int) $pagenum;
1383  
1384      $request = remove_query_arg( 'paged' );
1385  
1386      $home_root = parse_url(home_url());
1387      $home_root = ( isset($home_root['path']) ) ? $home_root['path'] : '';
1388      $home_root = preg_quote( trailingslashit( $home_root ), '|' );
1389  
1390      $request = preg_replace('|^'. $home_root . '|', '', $request);
1391      $request = preg_replace('|^/+|', '', $request);
1392  
1393      if ( !$wp_rewrite->using_permalinks() || is_admin() ) {
1394          $base = trailingslashit( get_bloginfo( 'url' ) );
1395  
1396          if ( $pagenum > 1 ) {
1397              $result = add_query_arg( 'paged', $pagenum, $base . $request );
1398          } else {
1399              $result = $base . $request;
1400          }
1401      } else {
1402          $qs_regex = '|\?.*?$|';
1403          preg_match( $qs_regex, $request, $qs_match );
1404  
1405          if ( !empty( $qs_match[0] ) ) {
1406              $query_string = $qs_match[0];
1407              $request = preg_replace( $qs_regex, '', $request );
1408          } else {
1409              $query_string = '';
1410          }
1411  
1412          $request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request);
1413          $request = preg_replace( '|^index\.php|', '', $request);
1414          $request = ltrim($request, '/');
1415  
1416          $base = trailingslashit( get_bloginfo( 'url' ) );
1417  
1418          if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) )
1419              $base .= 'index.php/';
1420  
1421          if ( $pagenum > 1 ) {
1422              $request = ( ( !empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( $wp_rewrite->pagination_base . "/" . $pagenum, 'paged' );
1423          }
1424  
1425          $result = $base . $request . $query_string;
1426      }
1427  
1428      $result = apply_filters('get_pagenum_link', $result);
1429  
1430      return $result;
1431  }
1432  
1433  /**
1434   * Retrieve next posts page link.
1435   *
1436   * Backported from 2.1.3 to 2.0.10.
1437   *
1438   * @since 2.0.10
1439   *
1440   * @param int $max_page Optional. Max pages.
1441   * @return string
1442   */
1443  function get_next_posts_page_link($max_page = 0) {
1444      global $paged;
1445  
1446      if ( !is_single() ) {
1447          if ( !$paged )
1448              $paged = 1;
1449          $nextpage = intval($paged) + 1;
1450          if ( !$max_page || $max_page >= $nextpage )
1451              return get_pagenum_link($nextpage);
1452      }
1453  }
1454  
1455  /**
1456   * Display or return the next posts page link.
1457   *
1458   * @since 0.71
1459   *
1460   * @param int $max_page Optional. Max pages.
1461   * @param boolean $echo Optional. Echo or return;
1462   */
1463  function next_posts( $max_page = 0, $echo = true ) {
1464      $output = esc_url( get_next_posts_page_link( $max_page ) );
1465  
1466      if ( $echo )
1467          echo $output;
1468      else
1469          return $output;
1470  }
1471  
1472  /**
1473   * Return the next posts page link.
1474   *
1475   * @since 2.7.0
1476   *
1477   * @param string $label Content for link text.
1478   * @param int $max_page Optional. Max pages.
1479   * @return string|null
1480   */
1481  function get_next_posts_link( $label = null, $max_page = 0 ) {
1482      global $paged, $wp_query;
1483  
1484      if ( !$max_page )
1485          $max_page = $wp_query->max_num_pages;
1486  
1487      if ( !$paged )
1488          $paged = 1;
1489  
1490      $nextpage = intval($paged) + 1;
1491  
1492      if ( null === $label )
1493          $label = __( 'Next Page &raquo;' );
1494  
1495      if ( !is_single() && ( $nextpage <= $max_page ) ) {
1496          $attr = apply_filters( 'next_posts_link_attributes', '' );
1497          return '<a href="' . next_posts( $max_page, false ) . "\" $attr>" . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label) . '</a>';
1498      }
1499  }
1500  
1501  /**
1502   * Display the next posts page link.
1503   *
1504   * @since 0.71
1505   * @uses get_next_posts_link()
1506   *
1507   * @param string $label Content for link text.
1508   * @param int $max_page Optional. Max pages.
1509   */
1510  function next_posts_link( $label = null, $max_page = 0 ) {
1511      echo get_next_posts_link( $label, $max_page );
1512  }
1513  
1514  /**
1515   * Retrieve previous posts page link.
1516   *
1517   * Will only return string, if not on a single page or post.
1518   *
1519   * Backported to 2.0.10 from 2.1.3.
1520   *
1521   * @since 2.0.10
1522   *
1523   * @return string|null
1524   */
1525  function get_previous_posts_page_link() {
1526      global $paged;
1527  
1528      if ( !is_single() ) {
1529          $nextpage = intval($paged) - 1;
1530          if ( $nextpage < 1 )
1531              $nextpage = 1;
1532          return get_pagenum_link($nextpage);
1533      }
1534  }
1535  
1536  /**
1537   * Display or return the previous posts page link.
1538   *
1539   * @since 0.71
1540   *
1541   * @param boolean $echo Optional. Echo or return;
1542   */
1543  function previous_posts( $echo = true ) {
1544      $output = esc_url( get_previous_posts_page_link() );
1545  
1546      if ( $echo )
1547          echo $output;
1548      else
1549          return $output;
1550  }
1551  
1552  /**
1553   * Return the previous posts page link.
1554   *
1555   * @since 2.7.0
1556   *
1557   * @param string $label Optional. Previous page link text.
1558   * @return string|null
1559   */
1560  function get_previous_posts_link( $label = null ) {
1561      global $paged;
1562  
1563      if ( null === $label )
1564          $label = __( '&laquo; Previous Page' );
1565  
1566      if ( !is_single() && $paged > 1 ) {
1567          $attr = apply_filters( 'previous_posts_link_attributes', '' );
1568          return '<a href="' . previous_posts( false ) . "\" $attr>". preg_replace( '/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $label ) .'</a>';
1569      }
1570  }
1571  
1572  /**
1573   * Display the previous posts page link.
1574   *
1575   * @since 0.71
1576   * @uses get_previous_posts_link()
1577   *
1578   * @param string $label Optional. Previous page link text.
1579   */
1580  function previous_posts_link( $label = null ) {
1581      echo get_previous_posts_link( $label );
1582  }
1583  
1584  /**
1585   * Return post pages link navigation for previous and next pages.
1586   *
1587   * @since 2.8
1588   *
1589   * @param string|array $args Optional args.
1590   * @return string The posts link navigation.
1591   */
1592  function get_posts_nav_link( $args = array() ) {
1593      global $wp_query;
1594  
1595      $return = '';
1596  
1597      if ( !is_singular() ) {
1598          $defaults = array(
1599              'sep' => ' &#8212; ',
1600              'prelabel' => __('&laquo; Previous Page'),
1601              'nxtlabel' => __('Next Page &raquo;'),
1602          );
1603          $args = wp_parse_args( $args, $defaults );
1604  
1605          $max_num_pages = $wp_query->max_num_pages;
1606          $paged = get_query_var('paged');
1607  
1608          //only have sep if there's both prev and next results
1609          if ($paged < 2 || $paged >= $max_num_pages) {
1610              $args['sep'] = '';
1611          }
1612  
1613          if ( $max_num_pages > 1 ) {
1614              $return = get_previous_posts_link($args['prelabel']);
1615              $return .= preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $args['sep']);
1616              $return .= get_next_posts_link($args['nxtlabel']);
1617          }
1618      }
1619      return $return;
1620  
1621  }
1622  
1623  /**
1624   * Display post pages link navigation for previous and next pages.
1625   *
1626   * @since 0.71
1627   *
1628   * @param string $sep Optional. Separator for posts navigation links.
1629   * @param string $prelabel Optional. Label for previous pages.
1630   * @param string $nxtlabel Optional Label for next pages.
1631   */
1632  function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) {
1633      $args = array_filter( compact('sep', 'prelabel', 'nxtlabel') );
1634      echo get_posts_nav_link($args);
1635  }
1636  
1637  /**
1638   * Retrieve comments page number link.
1639   *
1640   * @since 2.7.0
1641   *
1642   * @param int $pagenum Optional. Page number.
1643   * @return string
1644   */
1645  function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) {
1646      global $post, $wp_rewrite;
1647  
1648      $pagenum = (int) $pagenum;
1649  
1650      $result = get_permalink( $post->ID );
1651  
1652      if ( 'newest' == get_option('default_comments_page') ) {
1653          if ( $pagenum != $max_page ) {
1654              if ( $wp_rewrite->using_permalinks() )
1655                  $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged');
1656              else
1657                  $result = add_query_arg( 'cpage', $pagenum, $result );
1658          }
1659      } elseif ( $pagenum > 1 ) {
1660          if ( $wp_rewrite->using_permalinks() )
1661              $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged');
1662          else
1663              $result = add_query_arg( 'cpage', $pagenum, $result );
1664      }
1665  
1666      $result .= '#comments';
1667  
1668      $result = apply_filters('get_comments_pagenum_link', $result);
1669  
1670      return $result;
1671  }
1672  
1673  /**
1674   * Return the link to next comments page.
1675   *
1676   * @since 2.7.1
1677   *
1678   * @param string $label Optional. Label for link text.
1679   * @param int $max_page Optional. Max page.
1680   * @return string|null
1681   */
1682  function get_next_comments_link( $label = '', $max_page = 0 ) {
1683      global $wp_query;
1684  
1685      if ( !is_singular() || !get_option('page_comments') )
1686          return;
1687  
1688      $page = get_query_var('cpage');
1689  
1690      $nextpage = intval($page) + 1;
1691  
1692      if ( empty($max_page) )
1693          $max_page = $wp_query->max_num_comment_pages;
1694  
1695      if ( empty($max_page) )
1696          $max_page = get_comment_pages_count();
1697  
1698      if ( $nextpage > $max_page )
1699          return;
1700  
1701      if ( empty($label) )
1702          $label = __('Newer Comments &raquo;');
1703  
1704      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>';
1705  }
1706  
1707  /**
1708   * Display the link to next comments page.
1709   *
1710   * @since 2.7.0
1711   *
1712   * @param string $label Optional. Label for link text.
1713   * @param int $max_page Optional. Max page.
1714   */
1715  function next_comments_link( $label = '', $max_page = 0 ) {
1716      echo get_next_comments_link( $label, $max_page );
1717  }
1718  
1719  /**
1720   * Return the previous comments page link.
1721   *
1722   * @since 2.7.1
1723   *
1724   * @param string $label Optional. Label for comments link text.
1725   * @return string|null
1726   */
1727  function get_previous_comments_link( $label = '' ) {
1728      if ( !is_singular() || !get_option('page_comments') )
1729          return;
1730  
1731      $page = get_query_var('cpage');
1732  
1733      if ( intval($page) <= 1 )
1734          return;
1735  
1736      $prevpage = intval($page) - 1;
1737  
1738      if ( empty($label) )
1739          $label = __('&laquo; Older Comments');
1740  
1741      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>';
1742  }
1743  
1744  /**
1745   * Display the previous comments page link.
1746   *
1747   * @since 2.7.0
1748   *
1749   * @param string $label Optional. Label for comments link text.
1750   */
1751  function previous_comments_link( $label = '' ) {
1752      echo get_previous_comments_link( $label );
1753  }
1754  
1755  /**
1756   * Create pagination links for the comments on the current post.
1757   *
1758   * @see paginate_links()
1759   * @since 2.7.0
1760   *
1761   * @param string|array $args Optional args. See paginate_links().
1762   * @return string Markup for pagination links.
1763  */
1764  function paginate_comments_links($args = array()) {
1765      global $wp_rewrite;
1766  
1767      if ( !is_singular() || !get_option('page_comments') )
1768          return;
1769  
1770      $page = get_query_var('cpage');
1771      if ( !$page )
1772          $page = 1;
1773      $max_page = get_comment_pages_count();
1774      $defaults = array(
1775          'base' => add_query_arg( 'cpage', '%#%' ),
1776          'format' => '',
1777          'total' => $max_page,
1778          'current' => $page,
1779          'echo' => true,
1780          'add_fragment' => '#comments'
1781      );
1782      if ( $wp_rewrite->using_permalinks() )
1783          $defaults['base'] = user_trailingslashit(trailingslashit(get_permalink()) . 'comment-page-%#%', 'commentpaged');
1784  
1785      $args = wp_parse_args( $args, $defaults );
1786      $page_links = paginate_links( $args );
1787  
1788      if ( $args['echo'] )
1789          echo $page_links;
1790      else
1791          return $page_links;
1792  }
1793  
1794  /**
1795   * Retrieve shortcut link.
1796   *
1797   * Use this in 'a' element 'href' attribute.
1798   *
1799   * @since 2.6.0
1800   *
1801   * @return string
1802   */
1803  function get_shortcut_link() {
1804      $link = "javascript:
1805              var d=document,
1806              w=window,
1807              e=w.getSelection,
1808              k=d.getSelection,
1809              x=d.selection,
1810              s=(e?e():(k)?k():(x?x.createRange().text:0)),
1811              f='" . admin_url('press-this.php') . "',
1812              l=d.location,
1813              e=encodeURIComponent,
1814              u=f+'?u='+e(l.href)+'&t='+e(d.title)+'&s='+e(s)+'&v=4';
1815              a=function(){if(!w.open(u,'t','toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570'))l.href=u;};
1816              if (/Firefox/.test(navigator.userAgent)) setTimeout(a, 0); else a();
1817              void(0)";
1818  
1819      $link = str_replace(array("\r", "\n", "\t"),  '', $link);
1820  
1821      return apply_filters('shortcut_link', $link);
1822  }
1823  
1824  /**
1825   * Retrieve the home url for the current site.
1826   *
1827   * Returns the 'home' option with the appropriate protocol, 'https' if
1828   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
1829   * overridden.
1830   *
1831   * @package WordPress
1832   * @since 3.0.0
1833   *
1834   * @uses get_home_url()
1835   *
1836   * @param  string $path   (optional) Path relative to the home url.
1837   * @param  string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https'.
1838   * @return string Home url link with optional path appended.
1839  */
1840  function home_url( $path = '', $scheme = null ) {
1841      return get_home_url(null, $path, $scheme);
1842  }
1843  
1844  /**
1845   * Retrieve the home url for a given site.
1846   *
1847   * Returns the 'home' option with the appropriate protocol, 'https' if
1848   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
1849   * overridden.
1850   *
1851   * @package WordPress
1852   * @since 3.0.0
1853   *
1854   * @param  int $blog_id   (optional) Blog ID. Defaults to current blog.
1855   * @param  string $path   (optional) Path relative to the home url.
1856   * @param  string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https'.
1857   * @return string Home url link with optional path appended.
1858  */
1859  function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
1860      $orig_scheme = $scheme;
1861  
1862      if ( !in_array( $scheme, array( 'http', 'https' ) ) )
1863          $scheme = is_ssl() && !is_admin() ? 'https' : 'http';
1864  
1865      if ( empty( $blog_id ) || !is_multisite() )
1866          $url = get_option( 'home' );
1867      else
1868          $url = get_blog_option( $blog_id, 'home' );
1869  
1870      if ( 'http' != $scheme )
1871          $url = str_replace( 'http://', "$scheme://", $url );
1872  
1873      if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false )
1874          $url .= '/' . ltrim( $path, '/' );
1875  
1876      return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );
1877  }
1878  
1879  /**
1880   * Retrieve the site url for the current site.
1881   *
1882   * Returns the 'site_url' option with the appropriate protocol, 'https' if
1883   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
1884   * overridden.
1885   *
1886   * @package WordPress
1887   * @since 2.6.0
1888   *
1889   * @uses get_site_url()
1890   *
1891   * @param string $path Optional. Path relative to the site url.
1892   * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', or 'admin'.
1893   * @return string Site url link with optional path appended.
1894  */
1895  function site_url( $path = '', $scheme = null ) {
1896      return get_site_url(null, $path, $scheme);
1897  }
1898  
1899  /**
1900   * Retrieve the site url for a given site.
1901   *
1902   * Returns the 'site_url' option with the appropriate protocol, 'https' if
1903   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
1904   * overridden.
1905   *
1906   * @package WordPress
1907   * @since 3.0.0
1908   *
1909   * @param int $blog_id (optional) Blog ID. Defaults to current blog.
1910   * @param string $path Optional. Path relative to the site url.
1911   * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', or 'admin'.
1912   * @return string Site url link with optional path appended.
1913  */
1914  function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
1915      // should the list of allowed schemes be maintained elsewhere?
1916      $orig_scheme = $scheme;
1917      if ( !in_array( $scheme, array( 'http', 'https' ) ) ) {
1918          if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) )
1919              $scheme = 'https';
1920          elseif ( ( 'login' == $scheme ) && force_ssl_admin() )
1921              $scheme = 'https';
1922          elseif ( ( 'admin' == $scheme ) && force_ssl_admin() )
1923              $scheme = 'https';
1924          else
1925              $scheme = ( is_ssl() ? 'https' : 'http' );
1926      }
1927  
1928      if ( empty( $blog_id ) || !is_multisite() )
1929          $url = get_option( 'siteurl' );
1930      else
1931          $url = get_blog_option( $blog_id, 'siteurl' );
1932  
1933      if ( 'http' != $scheme )
1934          $url = str_replace( 'http://', "{$scheme}://", $url );
1935  
1936      if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false )
1937          $url .= '/' . ltrim( $path, '/' );
1938  
1939      return apply_filters( 'site_url', $url, $path, $orig_scheme, $blog_id );
1940  }
1941  
1942  /**
1943   * Retrieve the url to the admin area for the current site.
1944   *
1945   * @package WordPress
1946   * @since 2.6.0
1947   *
1948   * @param string $path Optional path relative to the admin url.
1949   * @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.
1950   * @return string Admin url link with optional path appended.
1951  */
1952  function admin_url( $path = '', $scheme = 'admin' ) {
1953      return get_admin_url(null, $path, $scheme);
1954  }
1955  
1956  /**
1957   * Retrieve the url to the admin area for a given site.
1958   *
1959   * @package WordPress
1960   * @since 3.0.0
1961   *
1962   * @param int $blog_id (optional) Blog ID. Defaults to current blog.
1963   * @param string $path Optional path relative to the admin url.
1964   * @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.
1965   * @return string Admin url link with optional path appended.
1966  */
1967  function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) {
1968      $url = get_site_url($blog_id, 'wp-admin/', $scheme);
1969  
1970      if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
1971          $url .= ltrim($path, '/');
1972  
1973      return apply_filters('admin_url', $url, $path, $blog_id);
1974  }
1975  
1976  /**
1977   * Retrieve the url to the includes directory.
1978   *
1979   * @package WordPress
1980   * @since 2.6.0
1981   *
1982   * @param string $path Optional. Path relative to the includes url.
1983   * @return string Includes url link with optional path appended.
1984  */
1985  function includes_url($path = '') {
1986      $url = site_url() . '/' . WPINC . '/';
1987  
1988      if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
1989          $url .= ltrim($path, '/');
1990  
1991      return apply_filters('includes_url', $url, $path);
1992  }
1993  
1994  /**
1995   * Retrieve the url to the content directory.
1996   *
1997   * @package WordPress
1998   * @since 2.6.0
1999   *
2000   * @param string $path Optional. Path relative to the content url.
2001   * @return string Content url link with optional path appended.
2002  */
2003  function content_url($path = '') {
2004      $url = WP_CONTENT_URL;
2005      if ( 0 === strpos($url, 'http') && is_ssl() )
2006          $url = str_replace( 'http://', 'https://', $url );
2007  
2008      if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
2009          $url .= '/' . ltrim($path, '/');
2010  
2011      return apply_filters('content_url', $url, $path);
2012  }
2013  
2014  /**
2015   * Retrieve the url to the plugins directory or to a specific file within that directory.
2016   * You can hardcode the plugin slug in $path or pass __FILE__ as a second argument to get the correct folder name.
2017   *
2018   * @package WordPress
2019   * @since 2.6.0
2020   *
2021   * @param string $path Optional. Path relative to the plugins url.
2022   * @param string $plugin Optional. The plugin file that you want to be relative to - i.e. pass in __FILE__
2023   * @return string Plugins url link with optional path appended.
2024  */
2025  function plugins_url($path = '', $plugin = '') {
2026  
2027      $mu_plugin_dir = WPMU_PLUGIN_DIR;
2028      foreach ( array('path', 'plugin', 'mu_plugin_dir') as $var ) {
2029          $$var = str_replace('\\' ,'/', $$var); // sanitize for Win32 installs
2030          $$var = preg_replace('|/+|', '/', $$var);
2031      }
2032  
2033      if ( !empty($plugin) && 0 === strpos($plugin, $mu_plugin_dir) )
2034          $url = WPMU_PLUGIN_URL;
2035      else
2036          $url = WP_PLUGIN_URL;
2037  
2038      if ( 0 === strpos($url, 'http') && is_ssl() )
2039          $url = str_replace( 'http://', 'https://', $url );
2040  
2041      if ( !empty($plugin) && is_string($plugin) ) {
2042          $folder = dirname(plugin_basename($plugin));
2043          if ( '.' != $folder )
2044              $url .= '/' . ltrim($folder, '/');
2045      }
2046  
2047      if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
2048          $url .= '/' . ltrim($path, '/');
2049  
2050      return apply_filters('plugins_url', $url, $path, $plugin);
2051  }
2052  
2053  /**
2054   * Retrieve the site url for the current network.
2055   *
2056   * Returns the site url with the appropriate protocol, 'https' if
2057   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
2058   * overridden.
2059   *
2060   * @package WordPress
2061   * @since 3.0.0
2062   *
2063   * @param string $path Optional. Path relative to the site url.
2064   * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', or 'admin'.
2065   * @return string Site url link with optional path appended.
2066  */
2067  function network_site_url( $path = '', $scheme = null ) {
2068      global $current_site;
2069  
2070      if ( !is_multisite() )
2071          return site_url($path, $scheme);
2072  
2073      $orig_scheme = $scheme;
2074      if ( !in_array($scheme, array('http', 'https')) ) {
2075          if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) )
2076              $scheme = 'https';
2077          elseif ( ('login' == $scheme) && ( force_ssl_admin() ) )
2078              $scheme = 'https';
2079          elseif ( ('admin' == $scheme) && force_ssl_admin() )
2080              $scheme = 'https';
2081          else
2082              $scheme = ( is_ssl() ? 'https' : 'http' );
2083      }
2084  
2085      $url = $scheme . '://' . $current_site->domain . $current_site->path;
2086  
2087      if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
2088          $url .= ltrim($path, '/');
2089  
2090      return apply_filters('network_site_url', $url, $path, $orig_scheme);
2091  }
2092  
2093  /**
2094   * Retrieve the home url for the current network.
2095   *
2096   * Returns the home url with the appropriate protocol, 'https' if
2097   * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
2098   * overridden.
2099   *
2100   * @package WordPress
2101   * @since 3.0.0
2102   *
2103   * @param  string $path   (optional) Path relative to the home url.
2104   * @param  string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https'.
2105   * @return string Home url link with optional path appended.
2106  */
2107  function network_home_url( $path = '', $scheme = null ) {
2108      global $current_site;
2109  
2110      if ( !is_multisite() )
2111          return home_url($path, $scheme);
2112  
2113      $orig_scheme = $scheme;
2114  
2115      if ( !in_array($scheme, array('http', 'https')) )
2116          $scheme = is_ssl() && !is_admin() ? 'https' : 'http';
2117  
2118      $url = $scheme . '://' . $current_site->domain . $current_site->path;
2119  
2120      if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false )
2121          $url .= ltrim( $path, '/' );
2122  
2123      return apply_filters( 'network_home_url', $url, $path, $orig_scheme);
2124  }
2125  
2126  /**
2127   * Retrieve the url to the admin area for the network.
2128   *
2129   * @package WordPress
2130   * @since 3.0.0
2131   *
2132   * @par