首先,我建议您使用函数返回要排除的术语,这将帮助您在不同的位置获取它们,而无需重复代码,例如在“pre\\u get\\u posts”过滤器和相邻的post过滤器中。
因此:
function get_level_term_to_exclude() {
if ( current_user_can (\'manage_options\') || current_user_can (\'view_level1_posts\') ) {
return false;
}
$terms = array( \'level1\', \'level2\', \'level3\' );
if( current_user_can ( \'view_level2_posts\' ) ) {
$terms = array( \'level1\' );
}
if( current_user_can ( \'view_level3_posts\' ) ) {
$terms = array( \'level1\', \'level2\' );
}
return $terms;
}
为了简洁起见,我删除了注释,但是您的代码注释得很好,我的注释就是从那里删除的。我只是把管理员的检查放在函数顶部。
之后,一般来说,JOIN
条款can\'t 过滤任何没有WHERE
, 和WHERE
如果使用中未定义的表名,则将失败JOIN
, so不存在连接方法和where方法,但存在连接方法和where方法。
在core中,排除术语的过滤通过以下两种方式完成\'WHERE\'
和JOIN
, 事实上,在第1183行,您可以看到:
"WHERE p.post_date $op %s AND p.post_type = %s
AND p.post_status = \'publish\' $posts_in_ex_terms_sql"
内部
if ( ! empty( $excluded_terms ) ) {
第1154行的声明
在线#1141:
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";
The
$posts_in_ex_terms_sql
以以下方式设置在第1173行:
$posts_in_ex_terms_sql = $wpdb->prepare(
" AND tt.taxonomy = %s
AND tt.term_id NOT IN (" . implode( $excluded_terms, \',\' ) . \')\', $taxonomy
);
我认为,当
$excluded_terms
不为空。。。如果它对core有效,那么它也应该对您有效。
因此,您可以使用"get_{$adjacent}_post_where"
过滤和"get_{$adjacent}_post_join"
.
那么函数filter_adjacent
应作用于join和where子句,对current_filter
我能做到这一点。
下面是使用我的提示显示您的班级的方式:
class Site_Members_Taxonomy {
const LANG = \'some_textdomain\';
public $post_types = array( \'post\', \'page\', \'gallery\' );
public $tax = \'membership\';
public $tax_label;
public function __construct() {
$this->tax_label = __( \'Membership\', self::LANG );
add_action( \'pre_get_posts\', array( $this, \'filter_query\' ) );
add_filter( \'get_previous_post_where\', array( $this, \'filter_adjacent\' ) );
add_filter( \'get_next_post_where\', array( $this, \'filter_adjacent\' ) );
add_filter( \'get_previous_post_join\', array( $this, \'filter_adjacent\' ) );
add_filter( \'get_next_post_join\', array( $this, \'filter_adjacent\' ) );
}
function get_term_to_exclude() {
if (
is_admin()
|| current_user_can (\'manage_options\')
|| current_user_can (\'view_level1_posts\')
) {
return false;
}
$terms = array( \'level1\', \'level2\', \'level3\' );
if( current_user_can ( \'view_level2_posts\' ) ) {
$terms = array( \'level1\' );
}
if( current_user_can ( \'view_level3_posts\' ) ) {
$terms = array( \'level1\', \'level2\' );
}
return $terms;
}
/**
* Modify the query based on membership taxonomy
*/
function filter_query( $query ) {
$terms = $this->get_term_to_exclude();
if ( ! $terms ) return;
$tax_query = array(
array(
\'taxonomy\' => $this->tax,
\'field\' => \'slug\',
\'terms\' => $terms,
\'operator\' => \'NOT IN\'
)
);
set_query_var( \'tax_query\', $tax_query );
}
/**
* Filter adjacent posts
*/
function filter_adjacent( $clause ) {
if ( substr_count( current_filter(), \'_post_join\' ) ) {
if ( empty($clause) ) $clause = \'\';
global $wpdb;
$clause .=
" INNER JOIN {$wpdb->term_relationships} trmship ON p.ID = trmship.object_id
INNER JOIN {$wpdb->term_taxonomy} ttmship
ON trmship.term_taxonomy_id = ttmship.term_taxonomy_id";
return $clause;
} elseif ( substr_count( current_filter(), \'_post_where\' ) ) {
$excluded_term_slugs = $this->get_term_to_exclude();
if ( ! $excluded_term_slugs ) return $clause;
$excluded_terms = array();
foreach ( $excluded_term_slugs as $slug ) {
$t = get_term_by( \'slug\', $slug, $this->tax );
if ( ! $t || is_wp_error($t) ) continue;
$excluded_terms[] = $t->term_id;
}
$excluded_terms = array_filter( array_map( \'intval\', $excluded_terms ) );
if ( empty( $excluded_terms ) ) return $clause;
global $wpdb;
$posts_in_ex_terms_sql = $wpdb->prepare(
" AND ttmship.taxonomy = \'%s\'
AND trmship.term_taxonomy_id NOT IN (" . implode( \',\', $excluded_terms ) . \')\',
$this->tax
);
return $clause. $posts_in_ex_terms_sql;
}
}
}
我为分类表使用了不同的别名,这样即使在
get_adjacent_post
任何条款都被传递给
$excluded_terms
参数和/或
$in_same_term
设置为true。
代码完全未经测试,请告诉我是否有效。。。