Skip to content

@3manuele /update_role
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Update role after which the user has read all the posts in a category
/*
* Function: Update role after the user has read all the posts in a category
*/
class WPSE78727
{
// set this to a proper name for a metakey
const METAKEY = 'user_read_posts';
public $user_ID = 0;
public $userdata = 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() && is_user_logged_in() && !current_user_can('manage_options') ) {
$this->get_user_data();
$updated = $this->save_post_id_in_user_meta();
$this->updated = ( is_string( $updated ) ) ? $updated : false;
}
}
public function get_user_data() {
$this->userdata = wp_get_current_user();
$this->user_ID = $this->userdata->ID;
//check the actual user role
foreach($this->role_sequence as $role){
if($this->userdata->has_cap($role)) $this->current_role = $role;
}
//if it haven't any of the roles I assign the lowest
if(!in_array($this->current_role, $this->role_sequence)){
$this->current_role = $this->role_sequence[0];
$this->userdata->add_role($this->current_role);
}
return true;
}
public function save_post_id_in_user_meta() {
global $post;
//if the post isn't part of the corresponding category to the current role do nothing
$categorie = array();
foreach(get_the_category( $post->ID ) as $category){
$categorie[] = $category->name;
}
if (!in_array($this->current_role, $categorie )) return;
// 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] ) )
$posts_read[$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 );
$new_role = $this->current_role;
if(isset($this->role_sequence[$key+1]))
$new_role = $this->role_sequence[$key+1];
$this->userdata->set_role($new_role);
return $new_role;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.