admin管理员组文章数量:1122846
Background:
I tried both and /, 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.
I decided to filter wp_post_data because all I want to do is change a post's status when first created, depending on how many posts the author has already created. Some suggested wp_insert_post_empty_content, but I think a better use-case is to allow them to create the actual post as a draft first, then ask them to get the proper membership to publish it.
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:
<?php
//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();
$author_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;
}
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.
I decided to filter wp_post_data because all I want to do is change a post's status when first created, depending on how many posts the author has already created. Some suggested wp_insert_post_empty_content, but I think a better use-case is to allow them to create the actual post as a draft first, then ask them to get the proper membership to publish it.
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:
<?php
//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();
$author_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;
}
Share
Improve this question
edited Jul 3, 2020 at 5:00
Simon Templar
asked Jun 23, 2020 at 21:27
Simon TemplarSimon Templar
32 bronze badges
1
- @Himad thanks for the edits. – Simon Templar Commented Jun 23, 2020 at 22:22
1 Answer
Reset to default 0Welcome to StackExchange! I made some changes to your code that I pointed out with comments. I'm not sure if this will actually work so you have to try it, and probably your way of echoing the message won't work because after updating there's a redirect so you'll have to work with the admin_notices
action and find some way to persist the message after redirection, however I think that's a topic for another question so I replaced the echoing part with an error_log
which will be enough to know if this is working as intended by looking at the logs.
<?php
add_filter('wp_insert_post_data', 'tml_filter_by_membership', 99, 2);
/*
When using a filter, the first argument is always the data to be modified and returned.
Usually you'll do your checks to see if you want to modify something, otherwise you'll return
the first argument ($data) so other filters can work as well. If you return nothing,
then you will probably break something. Here you should use $data instead of $postarr,
which are the same array but the later ($postarr) is unescaped.
*/
function tml_filter_by_membership($data, $postarr)
{
/* If you want to take only non-administrator users, don't check for capacity, check
instead for that specific role. */
if (!in_array('administrator', get_user_by('ID', $data['post_author'])->roles))
{
if ($data['post_type'] == 'gd_practitioner' || $data['post_type'] == 'gd_organization')
{
$membership_post_limits = tml_set_membership_post_limits_by_post_type();
$author_memberships = tml_get_post_author_memberships($data['post_author']);
$author_post_limit = tml_get_author_post_limit($author_memberships, $membership_post_limits, $data);
$number_of_published_posts_by_author = tml_get_author_published_posts($data);
/* I thought the last function was unnecessary so I just deleted it and moved
it's code in here. */
if ($number_of_published_posts_by_author >= $author_post_limit)
{
$data['post_status'] = 'draft';
/* Check yours logs to see if this is actually working. Displaying the
message is something you can solve afterwards. */
error_log('You have exceeded the number of listings for your membership');
}
/* Return your modified object. Before this, you were using a function which
returned something, but the return has to be inside the scope of the function linked to
the filter in order to actually return it. Previously you were returning nothing. */
return $data;
}
}
return $data;
}
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;
}
function tml_get_post_author_memberships($user_id)
{
if (class_exists('MeprUser'))
{
$user = new MeprUser($user_id);
$get_memberships = $user->active_product_subscriptions();
$author_memberships = array_values(array_unique($get_memberships));
return $author_memberships;
}
else
{
return false;
}
}
function tml_get_author_post_limit($author_memberships, $membership_post_limits, $data)
{
$author_post_limit = 1;
foreach ($author_memberships as $membership)
{
if ($author_post_limit < $membership_post_limits[$membership][$data['post_type']])
{
$author_post_limit = $membership_post_limits[$membership][$data['post_type']];
}
}
return $author_post_limit;
}
function tml_get_author_published_posts($data)
{
return count(get_posts(array(
'author' => $data['post_author'],
'post_type ' => $data['post_type'],
'numberposts ' => - 1,
'post_status ' => 'publish'
)));
}
本文标签: How to limit the number of custom posts certain users can publish in Wordpress using php script
版权声明:本文标题:How to limit the number of custom posts certain users can publish in Wordpress using php script? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736286042a1927585.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论