WordPress.org

Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#20643 closed defect (bug) (duplicate)

Custom Roles and Capabilities vs adding menu page for that user

Reported by: CyberSpy Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.3.2
Component: Users Keywords:
Focuses: Cc:

Description

As short as it might be:
Let's create a new role with one standard capability (so it can login and see backend) and one custom capability, to use later:

add_role( 'ranking_editor', 'Ranking Editor' );
$role =& get_role('ranking_editor'); 
$role->add_cap('read');
$role->add_cap('edit_ranking_strings');

(I pass intentionally how to do it, because it works well)

Then lets create a new admin page with setting, that can be accessed by a user with "Ranking Editor" role, and only this page will be seen by him:

add_action('admin_menu', 'add_rankings_page');
function add_rankings_page() {
	add_menu_page( 'Ranking', 'Ranking', 'edit_ranking_settings', 'ranking_settings', 'ranking_option_page' );
	add_action( 'admin_init', 'ranking_register_settings' );
}
function ranking_register_settings() {
	register_setting( 'ranking_options_group', 'ranking_value' );
}
function ranking_option_page() {?>
	<div class="wrap">
		<?php screen_icon('options-general'); ?>
		<h2>Some settings</h2>
		<form method="post" action="options.php">
			<?php settings_fields('ranking_options_group'); ?>
			<table class="form-table">
				<tr valign="top">
					<th scope="row"><label for="ranking_value">Some settings value</label></th>
					<td><input name="ranking_value" type="text" id="ranking_value" value="<?php form_option('ranking_value'); ?>" class="regular-text" /></td>
				</tr>
			</table>
		<?php do_settings_sections('ranking_options_group'); ?>
		<?php submit_button(); ?>
		</form>
	</div>
<?php }

(above goes to theme's function.php or as plugin, whatever).

Next step is to create new user whose role is Ranking Editor.
This user can login well, and he will see dashboard, profile, and newly created Ranking menu position. User can enter "Ranking settings", but trying to save anything inside gets:
"Cheatin' eh?"

The only solution for this problem is to add:

$role->add_cap('manage_options');

in first step, but this allows user to edit options, and that is not how problem should be fixed.
This is the only option which works, that custom role must have, so it can edit custom admin menu page that have this role attached to.

Change History (2)

comment:1 SergeyBiryukov2 years ago

  • Keywords needs-patch removed
  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

There's a typo in your add_cap() example: edit_ranking_strings should be edit_ranking_settings.

You should also add this in order to be able to save the settings:

function ranking_option_page_capability( $capability ) { 
	return 'edit_ranking_settings'; 
} 
add_filter( 'option_page_capability_ranking_options_group', 'ranking_option_page_capability' );

See #14365.

comment:2 CyberSpy2 years ago

Thank You so much.
typo in add_cap() was not a problem - this code is part of much biger project, and I had to cut it to as simple as possible, and rewrite some things by hand :)

But the function You have provided did the job :).

Thanks again.

Note: See TracTickets for help on using tickets.