只想澄清一下:
例如,您有“foo”、“bar”和“baz”等类别。角色为“foo”的新用户只能阅读类别为“foo”的帖子。在他们阅读完“foo”中的所有帖子后,他们的角色将更改为“bar”,以便他们可以阅读“bar”类别中的帖子。等等
一切都从一个好的计划开始,所以让我们制定一个计划。
第一件事是保留用户读取的帖子ID。每次用户打开帖子(即打开帖子的单个视图)时,我们都会保存该帖子的帖子ID如果我们保存一个帖子ID,我们必须检查用户是否阅读了所有需要的帖子才能更新到下一个级别。这意味着用户已经阅读了类别X中的所有帖子。如果用户已经阅读了所有必要的帖子,请将用户更新到下一级别听起来很容易,不是吗?我把它们都放在一个类中,因为这样可以节省一些代码,使一些事情变得更简单。使用调用此类$updated = new WPSE78727();
在单个帖子模板中(single.php
), e、 g.在模板的开头。
如果用户已更新,$updated->updated
设置为用户的新角色,否则设置为false。
<?php
class WPSE78727
{
// set this to a proper name for a metakey
const METAKEY = \'YourUserMetaKey\';
public $user_ID = 0;
public $user_data = null;
public $current_role = \'\';
public $updated = false;
// edit this to your needs
// this is the sequence of category names the user
// has to read to get updated to the next level
public $role_sequence = array(
\'foo\',
\'bar\',
\'baz\'
);
public function __construct() {
if( is_single() || user_is_logged_in() ) {
$this->get_user_data();
$updated = $this->save_post_id_in_user_meta();
$this->updated = ( is_string( $updated ) ) ?
$updated : false;
}
}
public function get_user_data() {
$user = wp_get_current_user();
$this->user_ID = $user->ID;
$this->user_data = get_userdata( $this->user_ID );
$this->current_role = $user_data->roles[0]; // get the first role
return true;
}
public function save_post_id_in_user_meta() {
global $post;
// make the code more readable
$role = &$this->current_role;
// $read_post should be an array
$posts_read = get_user_meta( $this->user_ID, self::METAKEY, true );
// be sure $posts_read is an array
if( ! is_array( $posts_read ) )
$posts_read = array();
// make an array for the post IDs which belongs to the current role
if( ! isset( $posts_read[$role] ) || ! is_array( $posts_read[$role] ) )
$read_posts[$role] = array();
// if the current post ID is not in the array, push it into the array
if( ! in_array( $post->ID, $posts_read[$role] ) )
array_push( $posts_read[$role], $post->ID );
// update the metadata
update_user_meta( $this->user_ID, self::METAKEY, $posts_read );
$new_role = $this->maybe_all_posts_read( $posts_read );
return ( ! is_array( $new_role ) ) ?
$new_role : $posts_read;
}
public function maybe_all_posts_read( $posts_read = array() ) {
$current_cat_id = get_cat_ID( $this->current_role );
// get all post IDs from this category
$post_ids = get_posts(
array(
\'numberposts\' => -1, // get all posts.
\'tax_query\' => array(
array(
\'taxonomy\' => \'category\',
\'field\' => \'id\',
\'terms\' => $current_cat_id,
),
),
\'fields\' => \'ids\', // Only get post IDs
));
// check if the user has read all posts. Simply check the differences between
// $post_ids (all post IDs in the current category (e.g. foo) and the read posts
// stored in user meta
$left_posts = array_diff( $post_ids, $posts_read[$this->current_role] );
// if no post is left, update the user
if( empty( $left_posts ) )
$new_role = $this->update_user();
return ( empty( $left_posts ) ) ?
$new_role : $left_posts;
}
public function update_user() {
// get the next role out of the sequence
$key = array_search( $this->current_role, $this->role_sequence );
// don\'t run out of the array!
$max = count( $this->role_sequence );
if( $key > $max )
$key = $max - 1;
$new_role = $role_sequence[$key+1];
// merge old and new data
$new_user_data = array_merge(
$this->user_data,
array(
\'ID\' => $id,
\'role\' => $new_role
)
);
// using wp_insert_user instead of wp_update_user without any reasons
wp_insert_user( $new_user_data );
return $new_role;
}
}
此代码未经测试,可能存在错误。它应该被视为一个起点,而不是一个完整的解决方案。