Minesh had just helped me get some code implemented that would disable comments on pages where the user did not have proper credentials (a combination of their role and the term associated with the post in the "access-control" taxonomy). We thought we had it working but that appears to no longer be the case. Can you please provide further assistance?
Below if the link to the original ticket:
https://toolset.com/forums/topic/disabling-comments-programmatically-on-a-single-page/page/2/
Below is an example page that is not working (comments show up when unauthenticated):
hidden link
hidden link
Below is the code that had been implemented:
// this script will disable comments on premium content if the user is not in the correct role
add_action( 'template_redirect', 'pp_disable_comments' );
function pp_disable_comments($post_object) {
// only run if single page
if (is_single()) {
$pp_disable_comments = false;
$user = wp_get_current_user();
$roles = (array) $user->roles;
// skip if user is contributor/author/editor/administrator OR if the post is public
if ((!in_array('contributor', $roles) && !in_array('contributor', $roles) && !in_array('author', $roles) && !in_array('editor', $roles) && !in_array('administrator', $roles)) || has_term('public', 'access-control')) {
// run if post is tier-0 only
if (has_term('tier-0', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-0', $roles) && !in_array('tier-1', $roles) && !in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
// run if post is tier-1 only
if (has_term('tier-1', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-1', $roles) && !in_array('tier-2')) {
$pp_disable_comments = true;
}
}
// run if post is tier-2 only
if (has_term('tier-2', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
}
// disable comments if required
if ($pp_disable_comments == true) {
global $post;
$post->comment_status="closed";
}
}
}
Hello and thank you for contacting Toolset support.
From what I could understand from the code, it will not be applied to guest users. If you want to disable comments for guests, add the following code at line 41:
if( !$user->ID ){
$pp_disable_comments = true;
}
Let me know what you will get.
Hi Jamal,
Good catch, although when I updated the code it did not have any effect. I tested to make sure the "run if not logged in and the post isn't public" section is running properly, which it is. It sets the pp_disabled_comments variable to true but the comments still render.
- Aaron
// this script will disable comments on premium content if the user is not in the correct role
add_action( 'template_redirect', 'pp_disable_comments' );
function pp_disable_comments($post_object) {
// only run if single page
if (is_single()) {
$pp_disable_comments = false;
$user = wp_get_current_user();
$roles = (array) $user->roles;
// skip if user is contributor/author/editor/administrator OR if the post is public
if ((!in_array('contributor', $roles) && !in_array('contributor', $roles) && !in_array('author', $roles) && !in_array('editor', $roles) && !in_array('administrator', $roles) && has_term('public', 'access-control') == false)) {
// run if not logged in and the post isn't public
if( !$user->ID && has_term('public', 'access-control') == false) {
$pp_disable_comments = true;
}
// run if post is tier-0 only
if (has_term('tier-0', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-0', $roles) && !in_array('tier-1', $roles) && !in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
// run if post is tier-1 only
if (has_term('tier-1', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-1', $roles) && !in_array('tier-2')) {
$pp_disable_comments = true;
}
}
// run if post is tier-2 only
if (has_term('tier-2', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
}
// disable comments if required
if ($pp_disable_comments == true) {
global $post;
$post->comment_status="closed";
}
}
}
I don't see any updates on this last code. Can you try this one:
// this script will disable comments on premium content if the user is not in the correct role
add_action( 'template_redirect', 'pp_disable_comments' );
function pp_disable_comments($post_object) {
// only run if single page
if (is_single()) {
$pp_disable_comments = false;
$user = wp_get_current_user();
$roles = (array) $user->roles;
// skip if user is contributor/author/editor/administrator OR if the post is public
if ((!in_array('contributor', $roles) && !in_array('contributor', $roles) && !in_array('author', $roles) && !in_array('editor', $roles) && !in_array('administrator', $roles)) || has_term('public', 'access-control')) {
// run if post is tier-0 only
if (has_term('tier-0', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-0', $roles) && !in_array('tier-1', $roles) && !in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
// run if post is tier-1 only
if (has_term('tier-1', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-1', $roles) && !in_array('tier-2')) {
$pp_disable_comments = true;
}
}
// run if post is tier-2 only
if (has_term('tier-2', 'access-control')) {
// check if user not in allowed roles
if (!in_array('tier-2', $roles)) {
$pp_disable_comments = true;
}
}
}
if( !$user->ID ){
$pp_disable_comments = true;
}
// disable comments if required
if ($pp_disable_comments == true) {
global $post;
$post->comment_status="closed";
}
}
}
If this does not help, allow me temporary access to your website to check this further. Your next reply will be private to let you share credentials safely. ** Make a database backup before sharing credentials. **
Thank you for the credentials. I have some doubts about some lines of codes, especially the first condition and why check against the public term, and line 28 about checking tier-2 in roles.
I just want to make sure that I understand the requirements, and I'll also need FTP access to access to debug.log file. I am setting your next reply to be private to let you share the FTP credentials.
Regarding the requirements, this is what I understood. Please correct me if I am wrong:
- Posts with the term public in taxonomy access-control should have comments enabled.
- Posts with the term tier-0 should have comments enabled only to users with the roles tier-0, tier-1, or tier-2.
- Posts with the term tier-1 should have comments enabled only to users with the roles tier-1 or tier-2.
- Posts with the term tier-2 should have comments enabled only to users with the role tier-2.
- For anything else, the comments should be disabled.
I correctly setup the domain/IP correctly but the WordPress credentials did not work for me. I wanted to create an admin user programmatically, but the FTP access are not working for me either.
Please reset the password again, and share it on your next private reply.
The credentials worked for me and I come up with the following code, which seems to me simpler and more readable:
add_action( 'template_redirect', 'pp_disable_comments' );
function pp_disable_comments($post_object) {
// only run if single page
if (is_single()) {
$pp_disable_comments = false;
$user = wp_get_current_user();
$roles = (array) $user->roles;
// When post is public
if ( has_term('public', 'access-control') ) {
$pp_disable_comments = true;
} else {
// When user has a default role contributor, author, editor, or administrator
if ( in_array('contributor', $roles) || in_array('author', $roles) || in_array('editor', $roles) || in_array('administrator', $roles) ) {
$pp_disable_comments = true;
} else {
// restricted content
// run if post is tier-0 only
if ( has_term('tier-0', 'access-control') ) {
// user should have a tier role
if ( in_array('tier-0', $roles ) || in_array('tier-1', $roles) || in_array('tier-2', $roles ) ) {
$pp_disable_comments = true;
}
}
if ( has_term('tier-1', 'access-control') ) {
// user should have tier-1 or tier-2
if ( in_array('tier-1', $roles) || in_array('tier-2', $roles ) ) {
$pp_disable_comments = true;
}
}
if ( has_term('tier-2', 'access-control') ) {
// user should have tier-2
if ( in_array('tier-2', $roles ) ) {
$pp_disable_comments = true;
}
}
}
}
// disable comments if required
if ($pp_disable_comments == true) {
global $post;
$post->comment_status = "closed";
}
}
}
Please test from your side and if something does not work as expected, please provide a test case to demonstrate it:
- Credentials of the user to test with.
- The post to test with.
Hi Jamal,
I incorporated your code, but changed your lines 22, 29, and 36 to be !in_array because, for example, if the post is set to require a minimum tier-1 access then access should only be denied if the user does NOT have a tier-1 or higher access role. For example:
if ( has_term('tier-1', 'access-control') ) {
// user should have tier-1 or tier-2
if ( !in_array('tier-1', $roles) && !in_array('tier-2', $roles ) ) {
$pp_disable_comments = true;
}
}
I also added a couple debug lines that will show if the disable_comments has been set (will show at the top of the page when rendered). When I visit the example page I paste below, it correctly shows that comments are set to be disabled.
Finally, I added some additional code in there that will redirect the browser to a content template for unauthenticated users, but this should not impact the code that you provided because that portion of the code still gets run. The code is all stored in Snippet ID 14 if you want to review.
You can check this code by going to the following URL while NOT logged in. Comments should not be getting displayed, but they are:
Example page: hidden link
Snippet with code: hidden link
- Aaron
Well the comments form is not displayed, which means that the comments status was correctly set by the custom code.
The existing comment needs to use another hook to hide them. Something like:
function df_disable_comments_hide_existing_comments($comments) {
$comments = array();
return $comments;
}
add_filter('comments_array', 'df_disable_comments_hide_existing_comments', 10, 2);
But that did not work, and it seems that the displayed comments are loaded by the wpDiscuz plugin. Please deactivate the plugin and its addons and check again. This way we can be sure if they are coming from WordPress or from the plugin.
Once we are sure they come from the plugin, we should search for a different hook if the plugin has one. The plugin's support is best placed to answer that.
Hi Jamal,
Adding that code to the snippet successfully hides comments when wpDiscuz is deactivated. I will reach out to their technical support and report back once I have an answer.
- Aaron
Awesome. I'll set this ticket as waiting for your reply, which should keep it open for a couple of weeks. You will receive email notifications before it gets closed.
Just replying to keep the cleanup bots at bay. I'm told by the plugin's developer that they'll be adding a hook, but they have not finished yet.
- Aaron
Hello Aaron, sure! I'll set this ticket as waiting for your feedback again. You will receive email notifications before it gets closed.