Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

UPDATE: For anyone following this thread, the plugin solution does work, but seems to have a problem on my multisite format. I have now tested on 3 individual installs and on 3 multisites. On the multisites, the red "undeletable" marker appears next to the categories in the array, but they can get deleted. This may well be down to a problem with my particular install, as it works properly with newly created subsites.

Original Post: Working on a multisite & would like a way to protect a couple of default categories from being deleted by site owners.

I'm already using the "members" plugin to define admin roles, but the only option there is "manage categories", and if I disable that capability they can't delete categories, but they can't create new ones either.

Any way to allow new categories but not to delete a few special ones??

share|improve this question
    
Updated answer. I forgot to mention since moment zero that the code was developed and tested in a Multisite environment. I really don't know why this would be failing on your side. A third party testing is needed. –  brasofilo Nov 19 '12 at 22:37
    
Just created a brand new subsite on my original test multisite & it works perfectly! Don't understand this at all. All the old sites I tested on still don't work, the new one does? Thanks –  speedypancake Nov 19 '12 at 23:01
    
I'm running 3.4.2. Just a guess: maybe another plugin is using the same hooks. Try modifying the actions priority (delete_term_taxonomy, edit_term_taxonomies). Instead of 10, try 1 (highest) or 9999 (lowest), i.e.: add_action( 'delete_term_taxonomy', 'wpse_70758_del_tax', 1, 1 ); –  brasofilo Nov 19 '12 at 23:19
    
@brasofilo - Thanks for your further input. I have tried your suggestions & disabled all site & network plugins but still refuses to protect cats from deletion. However, given that the plugin works properly with newly created subsites I'm happy to accept that it's an issue with my setup. Maybe something is corrupted - this multisite shares a common database & I've been doing a LOT of testing various things over the last few months. So kudos for coming up with a great answer to the challenge & then creating a plugin to make it work - Cheers :-) –  speedypancake Nov 20 '12 at 7:40
add comment

2 Answers

up vote 3 down vote accepted

Extending @Roman's answer.


The following was developed and tested in a Multisite environment - local and live WP installs.


Looking at the source of wp_delete_term, there are some hooks that are triggered when the function is called.

I'm not sure if this is the best way of doing this, but it works.

add_action( 'delete_term_taxonomy', 'wpse_70758_del_tax', 10, 1 );

function wpse_70758_del_tax( $tt_id )
{
    $undeletable = array( 'undeletable', 'uncategorized', 'other-cat' );
    $term = get_term_by( 'id', $tt_id, 'category' );

    if( in_array( $term->slug, $undeletable ) ) 
        wp_die( 'cant delete' );
}

So, when trying to delete the "Undeletable" category (using the Quick Edit menu), it produces:

can't delete category

As the deletion happens via Ajax, we are breaking its execution and WP dumps that error message (modifying that text deserves a separate Question).

If we use the "Bulk actions", that wp_die() is printed in the screen.


But that's not all. Before the actual deletion (action hook delete_term_taxonomy), the child categories of the one we are blocking are "unparented", line #1772:

// Update children to point to new parent

There's another hook where this action happens and we can insert an early break to prevent the "unparenting":

add_action( 'edit_term_taxonomies', 'wpse_70758_del_child_tax', 10, 1 );

function wpse_70758_del_child_tax( $arr_ids )
{
    $undeletable = array( 'undeletable', 'uncategorized', 'other-cat' );
    foreach( $arr_ids as $id )
    {
        $term   = get_term_by( 'id', $id, 'category' );
        $parent = get_term_by( 'id', $term->parent, 'category' );

        if( in_array( $parent->slug, $undeletable ) ) 
            wp_die( 'cant delete' );        
    }
}

Use this inside a Must Use Plugin and it will be automatically active in the network.


The snapshot above has a custom ID column in the category listing. That's done with the following code (an here with an extra column marking the "undeletable" categories with a big red bullet):

add_filter( 'manage_edit-category_columns', 'wpse_70758_cat_edit_columns' );
add_filter( 'manage_category_custom_column', 'wpse_70758_cat_custom_columns', 10, 3 );

function wpse_70758_cat_edit_columns( $columns )
{
    $columns['tt_id'] = 'ID';   
    $columns['undeletable'] = 'Undeletable';   
    return $columns;
}   

function wpse_70758_cat_custom_columns( $value, $name, $tt_id )
{
    if( 'tt_id' == $name ) 
        echo $tt_id;

    $term = get_term_by( 'id', $tt_id, 'category' );
    $undeletable = array( 'undeletable', 'uncategorized', 'other-cat' );

    if( 'undeletable' == $name && in_array( $term->slug, $undeletable ) )
        echo '<span style="color:#f00;font-size:5em;line-height:.5em">&#149;</span>';
}

Full working plugin: https://gist.github.com/4110831

share|improve this answer
    
Thanks for your input guys - I'll try and check this out over the weekend. –  speedypancake Nov 17 '12 at 9:56
    
Need a little more help with one I'm afraid. I added the first bit of code in functions.php and changed the 'undeletable' to an existing category & it worked perfectly. Got all excited and changed it again to 'product' but that category DID get deleted. Now tried creating a whole bunch of new categories but everything always gets deleted now? Did also try the rest of the code and the big red buttons showed up (nice touch) but categories still get deleted - any ideas what I'm doing wrong? THANKS –  speedypancake Nov 19 '12 at 9:13
    
@user22537 : I've modified all conditionals to use the in_array logic. So, you can check for a bunch of undeletable categories. Make sure the Category slug matches the list in the $undeletable arrays. –  brasofilo Nov 19 '12 at 11:12
    
I've tried to show the actual code I'm using in the answer above, but not sure if you will be able to see it? I created a new category called "bob". It shows the red undeletable besided it, but still gets deleted. Feel I must be doing something stupid - thanks for your support –  speedypancake Nov 19 '12 at 12:18
    
@user22537 please add code and other relevant details to your question rather that someone's answer (that makes things confusing). –  Rarst Nov 19 '12 at 12:31
show 9 more comments

Maybee you can hook to wp_delete_term function with action "delete_term" (see info at: http://adambrown.info/p/wp_hooks/hook/delete_term?version=3.4&file=wp-includes/taxonomy.php) and if such particular term is deleted, you can insert it once again...

this is not so clean solution and users would look bit surprised that term remains still after they clicked "delete link" but it can do the job, actually i think it is only solution...

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.