Gary Woods
Gary Woods

Reputation: 1011

Restrict certain tags from non-admins in Wordpress

I run a multiple author website. I want to restrict a few tags from being selected by my authors.

The only options that I found so far was techniques to replace the free tag text field with a list (similar to the category list). This is not a solution for me as I will need my authors to be able to create new tags.

Surely there must be a way to restrict specific tags from non-admins? Do you know how? Any brainstorming or proper solutions are welcome.

Upvotes: 0

Views: 1502

Answers (3)

Ituk
Ituk

Reputation: 61

based on crowjonah's wonderful answer, here is a function to remove multiple tags:

<?php           
/** block non-admins from using specific post tags **/
function remove_tags_function( $post_id ){
    if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
        $post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
        $pos = array_intersect( array('TAG1', 'TAG2', 'TAG3', 'ETC...'), $post_tags ); //check for the prohibited tag
        if( !empty($pos) ) { //if found
            $post_tags = array_diff($post_tags, $pos);
            wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
        }
    }//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}
add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function      
?>

Itamar

Upvotes: 0

crowjonah
crowjonah

Reputation: 2878

I think the ideal solution would be to conditionally filter the taxonomy query used in post_tags_meta_box as it ajaxes its suggestions, and maybe even providing some error-handling if someone tried to manually type the tag you don't want them to use, but I'm not aware of a filter that could aid in pulling that off.

Expanding on Giordano's suggestion and referencing this other question, you could use something like this in functions.php

add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function

function remove_tags_function( $post_id ){
    if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
        $post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
        $pos = array_search( 'tag-to-be-deleted', $post_tags ); //check for the prohibited tag
        if( false !== $pos ) { //if found
            unset( $post_tags[$pos] ); //unset the tag
            wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
        }
    }//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}

Non-admin users will still be able to type in and add tag-to-be-deleted, but it will not stick to the post. Once saved, the tag will be stripped. If the user is really dedicated, they could spell it differently, or, as you saw, change the capitalization, but whatever they do it wont technically be the same tag, and you will be able to keep it pure for whatever theme purpose you need. I can't imagine a situation in which a user without admin capabilities could add the forbidden tag, but I know better than to never say never.

If you want to allow certain non-admin users to assign the forbidden tag to a post, you'll have to revise the parameter passed into line 4 if(!current_user_can('...'){. For information on other capabilities you can pass to this conditional statement, check the Wordpress documentation of Roles & Capabilities. It's much easier to check for a capability than a role, so pick a logical capability that is restricted to the levels of user that you wish to be exempt from the tag deletion.

Upvotes: 1

Giordano B.
Giordano B.

Reputation: 116

You could probably create a simple plugin that deletes the specified tags from the post when saved if the author is not you. You can call your function when the post is saved with add_action('save_post', 'remove_tags_function',10,2);

Then you would create a function like

function remove_tags_function($postID, $post){
if($parent_id = wp_is_post_revision($postID))
    {
    $postID = $parent_id;
    $post = get_post($postID);
    }
if($post->post_author != 'YOUR AUTHOR NUMBER'){
$tags = wp_get_post_tags( $post_id );
$i = 0;
foreach($tags as $tag){
 if(in_array("TAG NAME", $tag)) unset $tags[$i];
 $i++;
}

}}

I have not tested it, but logically it would work.

EDIT:

That's not gonna work!

Try to put the following in a .php file in your plugin folder. Not tested for now, but it looks fine.

<?php
add_action('save_post', 'remove_tags_function',10,2);
        function remove_tags_function($postID, $post){
        if($parent_id = wp_is_post_revision($postID))
            {
            $postID = $parent_id;
            $post = get_post($postID);
            }
        $user_info = $user_info = get_userdata($post->post_author);
        if($user_info->user_level != 10){ // 10 = admin
        untag_post($postID, array('TAGS', ... ));

        }}
        function untag_post($post_ids, $tags) {
        global $wpdb;
        if(! is_array($post_ids) ) {
            $post_ids = array($post_ids);
        }
        if(! is_array($tags) ) {
            $tags = array($tags);
        }

        foreach($post_ids as $post_id) {
            $terms = wp_get_object_terms($post_id, 'post_tag');
            $newterms = array();
            foreach($terms as $term) {
                if ( !in_array($term->name,$tags) ) { //$term will be a wordpress Term object.
                    $newterms[] = $term;
                }
            }
            wp_set_object_terms($post_id, $newterms, 'post_tag', FALSE);
        }
    } // I got this from http://wordpress.stackexchange.com/questions/49248/remove-tags-from-posts-in-php/49256#49256
?>

Upvotes: 0

Related Questions