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.

I was surprised to discover that add_role() modifies the database and fails if the role already exists. There are two implications here, one first more serious than the other: 1) if you're in development and update your add_role code, you must first remove_role() 2) once you have it right, you should never have to run that code again.

So typically I have been putting my add_role() inside a wp_loaded action hook. And since I'm in development, I've also added a remove_role() before my add_role so I can be sure that if I modify my list of caps, it will actually take effect.

But clearly this is now being run every time a page of the blog is being accessed. Okay, I could put it in an admin-only action, or I could create a plugin page maybe under Users or Tools where this role can be created once. I guess I'm hoping there's a simpler, more elegant solution out there.

I don't imagine there's a run_once kind of action is there?

Or is the best practice just to add the role and then use add_cap() a bunch of times? And even then I imagine add_cap is accessing the db.

Just thinking in terms of the best way to reduce unncessary db access. What are your best practices?

share|improve this question
    
Awesome! Thanks for this question..Just adding remove_role() function before add_role() helped me. –  dino May 10 '13 at 2:06

1 Answer 1

up vote 4 down vote accepted

The user roles and capabilities are saved in the database so once you have you have used add_role() its saved and then next load WordPress will know that role just like the built in roles.

Now if you look at the function add_role() more specifically at line 141 you will see that it only saves the role and capabilities in the database if the var $use_db is set to true (which he is by default) so you can simply change it before you call your add_role() function and the role won't be saved.

try:

//globalize $wp_roles
global $wp_roles;
//set use_db to flase
$wp_roles->use_db = false;
//then add your role
$wp_roles->add_role( $role, $display_name, $capabilities );

Update:

If its in a test/development environment then i see no downside, but if you are on a live environment then you save the time it take to create that on role every load.

As for best practice run once, if in a plugin you should use register_activation_hook and for any thing else i use a simple custom made conditional function:

function run_once($key){
    $test_case = get_option('run_once');
    if (isset($test_case[$key]) && $test_case[$key]){
        return false;
    }else{
        $test_case[$key] = true;
        update_option('run_once',$test_case);
        return true;
    }
}

**usage:**
if (run_once('add_user_role')){
    //do you stuff and it will only run once
}
share|improve this answer
    
Aw crap. I even knew about that too from some earlier rooting about the WP_Roles class. Can you think of any downside to NOT using the database for roles? And is there a WP best practice for doing something only once? –  Tom Auger Aug 11 '11 at 17:31
    
Thanks for the update - I like the simplicity of the update_option solution –  Tom Auger Aug 16 '11 at 9:32

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.