在用户阅读了某个类别中的所有帖子后更改角色

时间:2013-01-08 作者:Emanuele

我正在创建一个平台,其中包含“X”类别和每个类别具有相同名称的“X”角色。

我想知道在用户阅读了某个类别中的所有帖子后,如何更改用户的角色。角色更改时,用户将有权访问下一个类别。

为了使类别私有化并创建相关的用户组,我使用Role Scoper 插件。

此解决方案与我的意思非常相似:https://stackoverflow.com/questions/9181440/wordpress-change-user-role-conditionally

谢谢

1 个回复
SO网友:Ralf912

只想澄清一下:
例如,您有“foo”、“bar”和“baz”等类别。角色为“foo”的新用户只能阅读类别为“foo”的帖子。在他们阅读完“foo”中的所有帖子后,他们的角色将更改为“bar”,以便他们可以阅读“bar”类别中的帖子。等等

一切都从一个好的计划开始,所以让我们制定一个计划。

第一件事是保留用户读取的帖子ID。每次用户打开帖子(即打开帖子的单个视图)时,我们都会保存该帖子的帖子ID$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;

    }

}
此代码未经测试,可能存在错误。它应该被视为一个起点,而不是一个完整的解决方案。

结束

相关推荐

尝试将分类法添加到Get_Categories(),但不起作用。如何解决这个问题?

我购买了这个模板,我正在尝试自定义。我添加了一个名为location的新分类法类别,并试图用新的分类法类别替换主题中加载的默认类别。以下是当前代码及其加载类别的位置: $cats_array = get_categories(\'hide_empty=0\'); $pages_array = get_pages(\'hide_empty=0\'); $site_pages = array(); $site_cats = array(); foreach (