Index: wp-includes/link-template.php
===================================================================
--- wp-includes/link-template.php	(revision 21425)
+++ wp-includes/link-template.php	(working copy)
@@ -1091,12 +1091,13 @@
  *
  * @since 1.5.0
  *
- * @param bool $in_same_cat Optional. Whether post should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  */
-function get_previous_post($in_same_cat = false, $excluded_categories = '') {
-	return get_adjacent_post($in_same_cat, $excluded_categories);
+function get_previous_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	return get_adjacent_post( $in_same_term, $excluded_terms, true, $taxonomy );
 }
 
 /**
@@ -1104,12 +1105,13 @@
  *
  * @since 1.5.0
  *
- * @param bool $in_same_cat Optional. Whether post should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  */
-function get_next_post($in_same_cat = false, $excluded_categories = '') {
-	return get_adjacent_post($in_same_cat, $excluded_categories, false);
+function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	return get_adjacent_post( $in_same_term, $excluded_terms, false, $taxonomy );
 }
 
 /**
@@ -1119,51 +1121,51 @@
  *
  * @since 2.5.0
  *
- * @param bool $in_same_cat Optional. Whether post should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  * @param bool $previous Optional. Whether to retrieve previous post.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  */
-function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $previous = true ) {
+function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
 	global $post, $wpdb;
 
-	if ( empty( $post ) )
+	if ( empty( $post ) || ! taxonomy_exists( $taxonomy ) )
 		return null;
 
 	$current_post_date = $post->post_date;
 
 	$join = '';
-	$posts_in_ex_cats_sql = '';
-	if ( $in_same_cat || ! empty( $excluded_categories ) ) {
+	$posts_in_ex_terms_sql = '';
+	if ( $in_same_term || ! empty( $excluded_terms ) ) {
 		$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";
 
-		if ( $in_same_cat ) {
-			$cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids'));
-			$join .= " AND tt.taxonomy = 'category' AND tt.term_id IN (" . implode(',', $cat_array) . ")";
+		if ( $in_same_term ) {
+			$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
+			$join .= $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id IN (" . implode( ',', array_map( 'intval', $term_array ) ) . ")", $taxonomy );
 		}
 
-		$posts_in_ex_cats_sql = "AND tt.taxonomy = 'category'";
-		if ( ! empty( $excluded_categories ) ) {
-			if ( ! is_array( $excluded_categories ) ) {
-				// back-compat, $excluded_categories used to be IDs separated by " and "
-				if ( strpos( $excluded_categories, ' and ' ) !== false ) {
-					_deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded categories.' ), "'and'" ) );
-					$excluded_categories = explode( ' and ', $excluded_categories );
+		$posts_in_ex_terms_sql = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
+		if ( ! empty( $excluded_terms ) ) {
+			if ( ! is_array( $excluded_terms ) ) {
+				// back-compat, $excluded_terms used to be IDs separated by " and "
+				if ( strpos( $excluded_terms, ' and ' ) !== false ) {
+					_deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) );
+					$excluded_terms = explode( ' and ', $excluded_terms );
 				} else {
-					$excluded_categories = explode( ',', $excluded_categories );
+					$excluded_terms = explode( ',', $excluded_terms );
 				}
 			}
 
-			$excluded_categories = array_map( 'intval', $excluded_categories );
+			$excluded_terms = array_map( 'intval', $excluded_terms );
 
-			if ( ! empty( $cat_array ) ) {
-				$excluded_categories = array_diff($excluded_categories, $cat_array);
-				$posts_in_ex_cats_sql = '';
+			if ( ! empty( $term_array ) ) {
+				$excluded_terms = array_diff( $excluded_terms, $term_array );
+				$posts_in_ex_terms_sql = '';
 			}
 
-			if ( !empty($excluded_categories) ) {
-				$posts_in_ex_cats_sql = " AND tt.taxonomy = 'category' AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')';
-			}
+			if ( !empty( $excluded_terms ) )
+				$posts_in_ex_terms_sql = $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id NOT IN (" . implode( $excluded_terms, ',' ) . ')', $taxonomy );
 		}
 	}
 
@@ -1171,21 +1173,21 @@
 	$op = $previous ? '<' : '>';
 	$order = $previous ? 'DESC' : 'ASC';
 
-	$join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cat, $excluded_categories );
-	$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 );
+	$join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms );
+	$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_terms_sql", $current_post_date, $post->post_type), $in_same_term, $excluded_terms );
 	$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );
 
 	$query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort";
-	$query_key = 'adjacent_post_' . md5($query);
-	$result = wp_cache_get($query_key, 'counts');
+	$query_key = 'adjacent_post_' . md5( $query );
+	$result = wp_cache_get( $query_key, 'counts' );
 	if ( false !== $result )
 		return $result;
 
-	$result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort");
+	$result = $wpdb->get_row( "SELECT p.* FROM $wpdb->posts AS p $join $where $sort" );
 	if ( null === $result )
 		$result = '';
 
-	wp_cache_set($query_key, $result, 'counts');
+	wp_cache_set( $query_key, $result, 'counts' );
 	return $result;
 }
 
@@ -1197,32 +1199,33 @@
  * @since 2.8.0
  *
  * @param string $title Optional. Link title format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
+ * @param string $taxonony Options, default is category. Taxonomy, if $in_same_term is true.
  * @return string
  */
-function get_adjacent_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $previous = true) {
+function get_adjacent_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
 	if ( $previous && is_attachment() && is_object( $GLOBALS['post'] ) )
 		$post = & get_post($GLOBALS['post']->post_parent);
 	else
-		$post = get_adjacent_post($in_same_cat,$excluded_categories,$previous);
+		$post = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy );
 
 	if ( empty($post) )
 		return;
 
-	if ( empty($post->post_title) )
+	if ( empty( $post->post_title ) )
 		$post->post_title = $previous ? __('Previous Post') : __('Next Post');
 
-	$date = mysql2date(get_option('date_format'), $post->post_date);
+	$date = mysql2date( get_option( 'date_format' ), $post->post_date );
 
-	$title = str_replace('%title', $post->post_title, $title);
-	$title = str_replace('%date', $date, $title);
-	$title = apply_filters('the_title', $title, $post->ID);
+	$title = str_replace( '%title', $post->post_title, $title );
+	$title = str_replace( '%date', $date, $title );
+	$title = apply_filters( 'the_title', $title, $post->ID );
 
 	$link = $previous ? "<link rel='prev' title='" : "<link rel='next' title='";
 	$link .= esc_attr( $title );
-	$link .= "' href='" . get_permalink($post) . "' />\n";
+	$link .= "' href='" . get_permalink( $post ) . "' />\n";
 
 	$adjacent = $previous ? 'previous' : 'next';
 	return apply_filters( "{$adjacent}_post_rel_link", $link );
@@ -1234,12 +1237,13 @@
  * @since 2.8.0
  *
  * @param string $title Optional. Link title format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function adjacent_posts_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
-	echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true);
-	echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false);
+function adjacent_posts_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', true, $taxonomy );
+	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', false, $taxonomy );
 }
 
 /**
@@ -1261,11 +1265,12 @@
  * @since 2.8.0
  *
  * @param string $title Optional. Link title format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function next_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
-	echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false);
+function next_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', false, $taxonomy );
 }
 
 /**
@@ -1274,56 +1279,72 @@
  * @since 2.8.0
  *
  * @param string $title Optional. Link title format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function prev_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
-	echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true);
+function prev_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', true, $taxonomy );
 }
 
 /**
  * Retrieve boundary post.
  *
  * Boundary being either the first or last post by publish date within the constraints specified
- * by $in_same_cat or $excluded_categories.
+ * by $in_same_term or $excluded_terms.
  *
  * @since 2.8.0
  *
- * @param bool $in_same_cat Optional. Whether returned post should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether returned post should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
  * @param bool $start Optional. Whether to retrieve first or last post.
+ * @param $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  * @return object
  */
-function get_boundary_post( $in_same_cat = false, $excluded_categories = '', $start = true ) {
+function get_boundary_post( $in_same_term = false, $excluded_terms = '', $start = true, $taxonomy = 'category' ) {
 	global $post;
 
-	if ( empty($post) || ! is_single() || is_attachment() )
+	if ( empty( $post ) || ! is_single() || is_attachment() || ! taxonomy_exists( $taxonomy ) )
 		return null;
 
-	$cat_array = array();
-	if( ! is_array( $excluded_categories ) )
-		$excluded_categories = explode( ',', $excluded_categories );
+	$query_args = array(
+		'posts_per_page' => 1,
+		'order' => $start ? 'ASC' : 'DESC',
+		'update_post_term_cache' => false,
+		'update_post_meta_cache' => false
+	);
 
-	if ( $in_same_cat || ! empty( $excluded_categories ) ) {
-		if ( $in_same_cat )
-			$cat_array = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'ids' ) );
+	$term_array = array();
 
-		if ( ! empty( $excluded_categories ) ) {
-			$excluded_categories = array_map( 'intval', $excluded_categories );
-			$excluded_categories = array_diff( $excluded_categories, $cat_array );
+	if( ! is_array( $excluded_terms ) ) {
+		if( ! empty( $excluded_terms ) )
+			$excluded_terms = explode( ',', $excluded_terms );
+		else
+			$excluded_terms = array();
+	}
 
-			$inverse_cats = array();
-			foreach ( $excluded_categories as $excluded_category )
-				$inverse_cats[] = $excluded_category * -1;
-			$excluded_categories = $inverse_cats;
+	if ( $in_same_term || ! empty( $excluded_terms ) ) {
+		if ( $in_same_term )
+			$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
+
+		if ( ! empty( $excluded_terms ) ) {
+			$excluded_terms = array_map( 'intval', $excluded_terms );
+			$excluded_terms = array_diff( $excluded_terms, $term_array );
+
+			$inverse_terms = array();
+			foreach ( $excluded_terms as $excluded_term ) {
+				$inverse_terms[] = $excluded_term * -1;
+			}
+			$excluded_terms = $inverse_terms;
 		}
+
+		$query_args[ 'tax_query' ] = array( array(
+			'taxonomy' => $taxonomy,
+			'terms' => array_merge( $term_array, $excluded_terms )
+		) );
 	}
 
-	$categories = implode( ',', array_merge( $cat_array, $excluded_categories ) );
-
-	$order = $start ? 'ASC' : 'DESC';
-
-	return get_posts( array('numberposts' => 1, 'category' => $categories, 'order' => $order, 'update_post_term_cache' => false, 'update_post_meta_cache' => false) );
+	return get_posts( $query_args );
 }
 
 /**
@@ -1333,11 +1354,12 @@
  *
  * @param string $format Optional. Link anchor format.
  * @param string $link Optional. Link permalink format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function previous_post_link($format='&laquo; %link', $link='%title', $in_same_cat = false, $excluded_categories = '') {
-	adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, true);
+function previous_post_link( $format='&laquo; %link', $link='%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, true, $taxonomy );
 }
 
 /**
@@ -1347,11 +1369,12 @@
  *
  * @param string $format Optional. Link anchor format.
  * @param string $link Optional. Link permalink format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function next_post_link($format='%link &raquo;', $link='%title', $in_same_cat = false, $excluded_categories = '') {
-	adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, false);
+function next_post_link( $format='%link &raquo;', $link='%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
+	adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, false, $taxonomy );
 }
 
 /**
@@ -1363,15 +1386,16 @@
  *
  * @param string $format Link anchor format.
  * @param string $link Link permalink format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
- * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs.
+ * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term.
+ * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded terms IDs.
  * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
+ * @param string $taxonomy Optional, default is category. Taxonomy, if $in_same_term is true.
  */
-function adjacent_post_link($format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true) {
+function adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
 	if ( $previous && is_attachment() )
 		$post = & get_post($GLOBALS['post']->post_parent);
 	else
-		$post = get_adjacent_post($in_same_cat, $excluded_categories, $previous);
+		$post = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy );
 
 	if ( !$post )
 		return;
