WordPress.org

Ready to get started?Download WordPress

Forums

How to add new user roles and capabilities? (18 posts)

  1. Arnan de Gans
    Member
    Posted 3 years ago #

    For a plugin i'm making i need some help with selecting user roles.

    I create/add some capabilities i add to existing roles which works fine. I also create a new userrole. Which also works fine.
    The problem lies in selecting that role.
    I've made a dropdown menu which lists all roles but selecting the right role often results in wrong access rights because the dropdown doesn't work right.

    My current code:

    $all_roles 		= $wp_roles->roles;
    $editable_roles = apply_filters('editable_roles', $all_roles);

    And the dropdown:

    <select name="miner_corp_statistics">
    	<?php foreach($editable_roles as $role) { ?>
    		<?php $capabilities = array_keys($role['capabilities']); ?>
    		<option value="<?php echo current($capabilities); ?>" <?php if(in_array($miner_config['corp_statistics'], $capabilities)) { echo 'selected'; } ?>><?php echo $role['name']; ?></option>
    	<?php }	unset($role);?>
    </select> Minimum required userlevel to see the statistics.

    This in essence works fine. But since it relies on in_array() its hardly reliable. For example if i select the subscriber role i almost always end up assigning my newly made role. Which obviously is wrong. I suspect this happens because of the capabilities assigned.

    The roles and capabilities are created using this code on plugin activation:

    add_role('miner_user', 'Corp Miner', array('read', 'miner_user'));
    add_role('miner_supervisor', 'Corp Supervisor', array('read', 'miner_user', 'miner_supervisor'));
    add_role('miner_administrator', 'Corp Administrator', array('read', 'miner_user','miner_supervisor', 'miner_administrator'));
    
    $wp_roles->add_cap('administrator','miner_user');
    $wp_roles->add_cap('administrator','miner_supervisor');
    $wp_roles->add_cap('administrator','miner_administrator');
    
    $wp_roles->add_cap('editor','miner_user');
    $wp_roles->add_cap('editor','miner_supervisor');
    $wp_roles->add_cap('editor','miner_administrator');

    Perhaps i'm missing something, perhaps i did it wrong entirely. I'm not sure. I've spend all evening on the codex and google yesterday with zero results on the dropdown. I did found out my way of adding the roles and capabilities is right.

    Any help is appreciated. Some tutorial, snippet, manual... Something to make this work. Thanks!

  2. Mark / t31os
    Moderator
    Posted 3 years ago #

    What is your dropdown doing?

    Please provide more details about what you intend for this dropdown menu to do.

  3. Arnan de Gans
    Member
    Posted 3 years ago #

    My plugin ads one role and several capabilities.
    Added capabilities are to ensure different layers of users having access to various bits of plugin. One of those capabilities is userstatistics.

    The new role should have "read" and "userstatistics" capabilities.

    This works fine!

    THe actual issue comes up with i want to select the new role. I've created dropdown menu's originally using the code above. But now i'm trying to use wp_dropdown_roles()

    However, whenever i use the above code when i select subscriber for a role the plugin falls back to my own created role.

    When i use the wp_dropdown_roles() function and i set a certain role. Then ONLY that role has access to the plugin. While that role is the minimum required.
    So when i set Editor as the role, only editors have access and not administrators or authors.

    So in short, the dropdown menu's seem broken, or coded wrong by me. And i cannot quite figure out what the proper way is.

  4. Mark / t31os
    Moderator
    Posted 3 years ago #

    I'm still not following how your dropdown is intended to function, is it part of a form that's submitting $_POST data?

    NOTE: Do you realise the option values in your dropdown are the value of whichever capability appears first in that given role's capability array.

  5. Arnan de Gans
    Member
    Posted 3 years ago #

    Yes i did read that.

    You're aware of the wp_dropdown_roles() function i assume. That lists all available roles in WP.

    <option value="administrator">Administrator</option>
    etc

    The chosen value is saved in an array in the db as part of my plugins options.
    The plugin then verifies with current_user_can() if that user can use a certain part of the plugin. This form saving is done using $_POST and works fine. But the verifying bit seems wrong. If i, for example, select editor. Then that value is saved and only the editors can access parts of the plugin.

    It seems to me that either i use a wrong function somewhere or wp doesnt interpret that role as the minimum requirement but the only option.

    Thanks for your time and replies!

  6. Mark / t31os
    Moderator
    Posted 3 years ago #

    Ok, let's put it this way..

    If i had you plugin loaded on my site, clicked on the dropdown, selected a role, what does your plugin then do(aim to do) after i've made that selection?

    Additionally, can i see the code that acts on that action please, ie. when a selection is made with the dropdown.

  7. Arnan de Gans
    Member
    Posted 3 years ago #

    It's simple really, i don't have the code here as im at work.. I'll post that later if you still need it.

    THe dropdown lists all roles.
    The plugin has several dashboard pages.
    Some pages are for admins, some pages are for other levels of access. Some pages are to be shown to every registered user and certain actions require a higher level.

    Thus, the dropdown simply sets a minimum level for a part of the plugin. Obviously there are multiple dropdowns for different pages / allowed actions.

    I don't see why i need to explain that 4 times. The dropdown simply should set a minimum required userlevel for parts of the plugin. That's all.

    I'll post my current code later today.

  8. Mark / t31os
    Moderator
    Posted 3 years ago #

    It's likely me more than you, i don't follow written descriptions very well, but given some code to look at or a visual representation i'll understand three times as fast.

    I'll check back when you've posted the appropriate code... ;)

  9. Arnan de Gans
    Member
    Posted 3 years ago #

    Hi, as promised :) here's my current code, this is from another plugin but has the exact same issue. Hence why these snippets will slightly differ from the ones in my first post.

    The form:

    $adrotate_config 	= get_option('adrotate_config');
    
    			<tr>
    				<th scope="row" valign="top">Global Statistics Page</th>
    				<td>
    					<select name="adrotate_globalstatistics">
    						<?php wp_dropdown_roles($adrotate_config['globalstatistics']); ?>
    					</select><br />
    					<span class="description">Role to review the global statistics.</span>
    				</td>
    				<th scope="row" valign="top">Advertiser Statistics Page</th>
    				<td>
    					<select name="adrotate_userstatistics">
    						<?php wp_dropdown_roles($adrotate_config['userstatistics']); ?>
    					</select><br />
    					<span class="description">Role to allow users/advertisers to see their statistics page.</span>
    				</td>
    			</tr>
    
    			<tr>
    				<th scope="row" valign="top">Manage/Add/Edit Ads</th>
    				<td>
    					<select name="adrotate_ad_manage">
    						<?php wp_dropdown_roles($adrotate_config['ad_manage']); ?>
    					</select><br />
    					<span class="description">Role to see and add/edit ads.</span>
    				</td>
    				<th scope="row" valign="top">Delete/Reset Ads</th>
    				<td>
    					<select name="adrotate_ad_delete">
    						<?php wp_dropdown_roles($adrotate_config['ad_delete']); ?>
    					</select><br />
    					<span class="description">Role to delete ads and reset stats.</span>
    				</td>
    			</tr>
    
    			<tr>
    				<th scope="row" valign="top">Manage/Add/Edit Groups</th>
    				<td>
    					<select name="adrotate_group_manage">
    						<?php wp_dropdown_roles($adrotate_config['group_manage']); ?>
    					</select><br />
    					<span class="description">Role to see and add/edit groups.</span>
    				</td>
    				<th scope="row" valign="top">Delete Groups</th>
    				<td>
    					<select name="adrotate_group_delete">
    						<?php wp_dropdown_roles($adrotate_config['group_delete']); ?>
    					</select><br />
    					<span class="description">Role to delete groups.</span>
    				</td>
    			</tr>
    
    			<tr>
    				<th scope="row" valign="top">Manage/Add/Edit Blocks</th>
    				<td>
    					<select name="adrotate_block_manage">
    						<?php wp_dropdown_roles($adrotate_config['block_manage']); ?>
    					</select><br />
    					<span class="description">Role to see and add/edit blocks.</span>
    				</td>
    				<th scope="row" valign="top">Delete Blocks</th>
    				<td>
    					<select name="adrotate_block_delete">
    						<?php wp_dropdown_roles($adrotate_config['block_delete']); ?>
    					</select><br />
    					<span class="description">Role to delete blocks.</span>
    				</td>
    			</tr>

    The code saving that form:

    $config['userstatistics'] 		= $_POST['adrotate_userstatistics'];
    	$config['globalstatistics'] 	= $_POST['adrotate_globalstatistics'];
    	$config['ad_manage'] 			= $_POST['adrotate_ad_manage'];
    	$config['ad_delete'] 			= $_POST['adrotate_ad_delete'];
    	$config['group_manage'] 		= $_POST['adrotate_group_manage'];
    	$config['group_delete'] 		= $_POST['adrotate_group_delete'];
    	$config['block_manage']			= $_POST['adrotate_block_manage'];
    	$config['block_delete'] 		= $_POST['adrotate_block_delete'];
    	update_option('adrotate_config', $config);

    Menu structure using the roles chosen in the form:

    function adrotate_dashboard() {
    	global $adrotate_config;
    
    	add_object_page('AdRotate', 'AdRotate', $adrotate_config['ad_manage'], 'adrotate', 'adrotate_manage');
    	add_submenu_page('adrotate', 'AdRotate > Manage Ads', 'Manage Ads', $adrotate_config['ad_manage'], 'adrotate', 'adrotate_manage');
    	add_submenu_page('adrotate', 'AdRotate > Groups', 'Manage Groups', $adrotate_config['group_manage'], 'adrotate-groups', 'adrotate_manage_group');
    	add_submenu_page('adrotate', 'AdRotate > Blocks', 'Manage Blocks', $adrotate_config['block_manage'], 'adrotate-blocks', 'adrotate_manage_block');
    	add_submenu_page('adrotate', 'AdRotate > User Statistics', 'User Statistics', $adrotate_config['userstatistics'], 'adrotate-userstatistics', 'adrotate_userstatistics');
    	add_submenu_page('adrotate', 'AdRotate > Global Statistics', 'Global Statistics', $adrotate_config['globalstatistics'], 'adrotate-statistics', 'adrotate_statistics');
    	add_submenu_page('adrotate', 'AdRotate > Settings','Settings', 'manage_options', 'adrotate-settings', 'adrotate_options');
    }

    And throughout the plugin thers various actions and functions that are limited by code like this:

    if($action == 'activate') {
    				if(current_user_can($adrotate_config['ad_manage'])) {
    					adrotate_active($banner_id, 'activate');
    					$result_id = $banner_id;
    				} else {
    					adrotate_return('no_access');
    				}
    			}

    As explained, it ALL works except the dropdowns. If in said dropdowns i select a certain role then only people having that role can access the dashboard or feature. Not higher or lower levels. Which obviously is wrong. The role in the dropdown should act as a MINIMUM required level.

    Thanks!

  10. Mark / t31os
    Moderator
    Posted 3 years ago #

    Just to confirm, the first piece of code you posted isn't complete right? It's not formed correctly if that's how the current code looks, it breaks into HTML without closing the PHP tag, ie. ?> .

  11. Arnan de Gans
    Member
    Posted 3 years ago #

    Correct, this is only part of the form. The form in itself (complete) works fine as in saves options etc as intended.

  12. Mark / t31os
    Moderator
    Posted 3 years ago #

    Is this..

    $adrotate_config 	= get_option('adrotate_config');

    Called in the same file as the following..

    function adrotate_dashboard() {
    	global $adrotate_config;

    Start dumping your variables at different points, and determine if they are holding what you expect them to hold, once you find where the data is lost/incorrect it will be a whole lot easier to isolate the problem..

    var_dump( $somevar );

    or

    print '<pre>';print_r( $somevar );print '</pre>';

    Just keep checking your data at different points in your script, narrow down the area where problems occur then let me know what you find, based on what you've posted i can't really tell to be honest.

  13. Arnan de Gans
    Member
    Posted 3 years ago #

    Yes i did that. All data is correct and saved correctly. Again, the form works fine.

    $adrotate_config = get_option('adrotate_config'); is set before the adrotate_dashboard() function and called specifically again in the options panel to ensure it uses the latest set there.

    The problem however is in how wordpress handles the roles/capabilities (or im using that api wrong).
    When i select the options in the dropdown it saves the correct values and uses the correct ones.

    But then current_user_can() seems to not pick up on that. Locking everyone out except the userrole chosen in the dropdown.

    As far as i could tell current_user_can does not cache anything so when that is called it checked in teh db which is up to date with my setting. And when i raise the user level to administrator the menu's immediately update as expected. Thus the globals works fine!

  14. Mark / t31os
    Moderator
    Posted 3 years ago #

    If you're passing the code to add menu pages a role, you're making that specific role the requirement to view that given page(i think).

    Despite the fact a role works, this wasn't intended behaviour, a capability should be given, not a role.

  15. Arnan de Gans
    Member
    Posted 3 years ago #

    Right, how do i make a dropdown for that. Since i had that at first (see initial post) and that didn't work either when i create an additional role.

  16. Mark / t31os
    Moderator
    Posted 3 years ago #

    Similar to how you did before(opening post), just be sure you're extracting an appropriate capability from the role, instead of just plucking out whatever comes first.

    You need to extract a capability specific to appliable roles, so for example, for something that both editors and admins can see, edit_pages would be appropriate (only admins and editors have that capability).

    There's a handy table you can reference here if it will help.
    http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table

  17. Arnan de Gans
    Member
    Posted 3 years ago #

    I see, hmm. Any suggestions as to how to get a specific capability to achieve that?

    The in_array() i've used wasn't reliable at all i found out.

  18. Arnan de Gans
    Member
    Posted 3 years ago #

    I'm giving up. In fact. I'm tempted to give up on wordpress for lacking documentation YET AGAIN.
    This whole thread (and forum for that matter) doesn't bring anything useful at all.

    Got any idea on my last question? Which actually was my first question.

    How to construct a dropdown menu that works?

    *sighs in frustration*

Topic Closed

This topic has been closed to new replies.

About this Topic