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?
1
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
}