Background:
I tried both https://wordpress.org/plugins/bainternet-posts-creation-limits and https://wordpress.org/plugins/limit-posts/, but they didn't work for some reason with my custom posts. So I decided to write my own php script, which I put into my child theme's function.php, to limit the number of certain custom posts types that certain users can create.
Structure:
I'm using wordpress 5.4.2 installed on bluehost. I am using geodirectory to create the custom post types (practitioners and organizations) and memberpress to manage permissions.
Constraints:
Because another plugin on my site gives privileges to only a particular role, I am giving everyone who is not an admin that particular user role and therefore cannot limit posting privileges by user role. That is why I am using memberpress membership to govern publishing capability.
Issue/What is wrong:
After running the code:
1- All users, instead of just the non-admins with insufficient memberships, cannot save new CPT's. Even the admin cannot save a CPT.
2- Users get this message when they click submit: "You do not have the privileges to perform this action." I wrote a different message to give to a user who has the wrong membership for this action.
Approach:
//Before a newly created post is saved to the database, filter by membership
add_filter( 'wp_insert_post_data' , 'tml_filter_by_membership' , 99, 2 );
/**
99 refers to the priority when this filter is executed; 99 indicates that it is one of the last filters executed on this action
2 indicates that we want both arguments given by the filter (because the second one contains sanitized but unmodified data--which is the data we want). Without 2, the function defaults to 1, giving us only slashed post data
**/
//filter by membership only acts on non-admin posts of certain post types
function tml_filter_by_membership( $data , $postarr ) {
//take only non-admin posts
if (! user_can($postarr['post_author'], 'manage_options')) {
// continue only if the post type is gd_practitioner or gd_studio
if ($postarr['post_type'] == 'gd_practitioner' || $postarr['post_type'] == 'gd_organization'){
//Set membership post limits by post_type
$membership_post_limits = tml_set_membership_post_limits_by_post_type();
//Get author's membership
$author_memberships = tml_get_post_author_memberships($postarr);
//Look up the author's post limit for that post type within the membership post limits array
$author_post_limit = tml_get_author_post_limit($author_memberships, $membership_post_limits, $postarr);
//Count author's published posts of the particular post type
$number_of_published_posts_by_author = tml_get_author_published_posts($postarr);
//Compare number of published posts to author's post limit and return $postarr
tml_compare_posts_to_limit($author_post_limit, $number_of_published_posts_by_author, $postarr);
}
}
}
//set membership post limits by post_type
function tml_set_membership_post_limits_by_post_type(){
$membership_post_limits=Array(
462 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
463 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
464 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
465 => Array ('gd_practitioner' =>10, 'gd_organization' =>10),
466 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
467 => Array ('gd_practitioner' =>10, 'gd_organization' =>10),
752 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
753 => Array ('gd_practitioner' =>1, 'gd_organization' =>1),
754 => Array ('gd_practitioner' =>1, 'gd_organization' =>1)
);
return $membership_post_limits;
}
//Get author's membership
function tml_get_post_author_memberships($postarr){
if( class_exists('MeprUser') ){
$user_id = $postarr['post_author'];
$user = new MeprUser( $user_id);
$get_memberships = $user->active_product_subscriptions();
$user_memberships = array_values( array_unique( $get_memberships ) );
return $author_memberships;
} else {
return false;
}
}
//Look up the author's post limit for that post type within the membership post limits array, using $postarr to give the post type, and $user_memberships to give the author's memberships
function tml_get_author_post_limit($author_memberships, $membership_post_limits, $postarr){
$author_post_limit=1;
Foreach ($author_memberships as $membership){
if ($author_post_limit < $membership_post_limits[$membership][$postarr['post_type']]){
$author_post_limit=$membership_post_limits[$membership][$postarr['post_type']];
}
}
return $author_post_limit;
}
//Count author's published posts of the particular post type
function tml_get_author_published_posts($postarr){
$posts = get_posts( array(
'author' => $postarr['post_author'],
'post_type '=> $postarr['post_type'],
'numberposts '=> -1,
'post_status '=> 'publish'
));
$number_of_published_posts_by_author=count($posts);
return $number_of_published_posts_by_author;
}
/**
//Another option, using count_user_posts function instead
function tml_get_author_published_posts($postarr){
$author= $postarr['post_author'];
$post_type = $postarr['post_type'];
$number_of_published_posts_by_author=count_user_posts($author, $post_type);
return $number_of_published_posts_by_author;
}
**/
//Compare number of published posts to author's post limit
function tml_compare_posts_to_limit($author_post_limit, $number_of_published_posts_by_author, $postarr){
$message="";
if ( $number_of_published_posts_by_author>= $author_post_limit){
$postarr['post_status']='draft';
$message="You have exceeded the number of listings for your membership";
}
echo "<div> ${message} </div>";
return $postarr;
}