Advertisement
Creative Coding

WordPress Roles and Capabilities: Building an Admin Interface

by

This is a four-part series tutorial covering the WordPress users, roles and capabilities topic. The series will cover the architecture and design of user roles in WordPress; highlight the most important functions for interacting with users and managing roles and capabilities; and in the last two articles, we are going to build a real-life example that demonstrates the usefulness of this API.


Introduction

In the last tutorial, we built a real-life example using the WordPress roles and capabilities system. The system is encapsulated in a single class; and can be used by initializing the class and passing parameters to it. The parameters are the array of users' IDs, another array of roles' names; and also a switch for allowing access to all users. In practice, you want the WordPress Administrator to be able to change those parameters; and thus control which users have a "client_dashboard" access.

In this tutorial, we'll build the interface which will give the Administrator the ability to automatically initialize our class and feed it with the adequate data. The interface will allow the admin to select roles, users; or opt in for full access.

The code for this new tutorial is available on the same Github repository. To access the previous code, navigate to the first commit of the repository. I've decided the keep the code unlicensed, so you are free to use it and license it as you see fit.


Why Do We Need an Interface?

Unlike users, WordPress provides no interface for roles. You can't add, remove or edit existing roles or capabilities without the help of a third-party plugin. You can, however, have a list of the existing roles in your blog from the dropdown list of role selection when editing an existing user profile. The interface limits you to selecting only one role for a particular user. Also, you can't assign capabilities to users with the default interface WordPress comes with.

For that reason, it's important that your plugin provides the required interface to configure its user access capabilities. Your plugin users should not rely on an external third-party plugin. Depending on the sophistication of your users, and their knowledge of the WordPress platform, they may want to:

  • Permit access to all users.
  • Limit access to some users.
  • Limit access to one or more roles.
  • A combination of users, and roles.

If you are a bit confused, here we are talking about a plugin which has two dashboards: One for the blog administrator, which has admin specific features and settings; and another one for select users, which has limited features and settings. So this example doesn't apply to all plugins out there; but only ones that requires admin and client access.

For that, we'll have two different interfaces: One for selecting roles, and another for selecting users. For role selection, we need to build a custom interface because WordPress has no visual interface for them. For user selection, we can leverage the already existing user profile page by adding additional custom fields.


Building the Role Selection Panel

WordPress comes with a small number of pre-defined roles: Administrator, Author, Contributor, Editor, and Subscriber. Knowledgeable WordPress users may add their own roles to categorize and manage their users. Because of that, our interface should fetch all the roles in the site, and offer the option to pick which ones to authorize client access. I also took the opportunity to stick the "all" switch to the same interface. Checking "all" will override your other settings.

Using the WordPress Settings API

To build the interface, we'll use the WordPress Settings API and create a custom function which will display the checkboxes. The following code is used to register the "wptuts_settings" settings form. We also register a section inside that form; and a field inside the section.

// Registers a new settings form
add_action('admin_init', 'wptuts_settings_form');
function wptuts_settings_form() {
	// Register a new settings form
	register_setting('wptuts_settings', 'wptuts_settings');

	// Register a new section
	add_settings_section('wptuts_settings', 'General Settings', 'wptuts_section', 'general_settings_form', 'Client Access');

	// Register a new field
	add_settings_field('client_roles', 'Client Roles', 'wptuts_roles_check', 'general_settings_form', 'wptuts_settings', array('client_roles', 'wptuts_settings'));
}

function wptuts_section() {
	return null;
}

The function add_settings_section() requires a function as its third parameter which returns the section description. To keep things simple, I passed a function that returns null (or nothing).

The function add_settings_field() accepts a field ID, a label, a function, the section and form to hook the field to; and the argument to pass to the field function. The field function will output the HTML code of the field.

The WordPress settings API is used to create forms that auto-magically save their content into a WordPress option. The option is "wptuts_settings", and is an array which has the different settings of our plugin. To make WordPress recognize our form fields, we need first to register them using the functions stated above; and also to assign the right name for each field. So each field will have a name in the form wptuts[field_name].

In our case, we have an unpredictable number of roles; and thus an unpredictable number of checkboxes. It doesn't make sense to create and register a field for each role. Luckily, HTML supports array elements; so we name our checkboxes wptuts[field_name][role_1], wptuts[field_name][role_2], wptuts[field_name][role_n]... WordPress will recognize this HTML array element and save it as a PHP array.

Below is the content of the "wptuts_settings" array when the "all", "author", and "subscriber" checkboxes are selected.

'wptuts_settings' =>
	array
		'client_roles' =>
			array
				'all' => string 'on' (length=2)
				'author' => string 'on' (length=2)
				'subscriber' => string 'on' (length=2)

Outputting the Field HTML Code

The function linked to the field is "wptuts_roles_check". It accepts an array which has the settings ID, and the field name; this makes our function reusable in other fields. You can overlook this parameter and hardcode the settings ID and field name into your function.

The function will loop through an array of roles' names returned by "$wp_roles->get_names()". It'll also unset the administrator role, and add an additional checkbox "all".

/**
 * Generates the roles checkboxes form
 *
 * @param array $param
 */
function wptuts_roles_check($param) {
	// Roles list
	$settings = get_option($param[1]);
	if (isset($settings[$param[0]])) {
		$val = $settings[$param[0]];
	}
	else {
		$val = '';
	}

	// Generate HTML Code
	// Get WP Roles
	global $wp_roles;
	$roles = $wp_roles->get_names();
	unset($roles['administrator']);
	// Generate HTML code
	if ($val['all'] === 'on') {
		echo '<input type="checkbox" name="' . $param[1] . '[' . $param[0] . '][all]" id="' . $param[0] . '[all]" checked/>  All<br />';
	}
	else {
		echo '<input type="checkbox" name="' . $param[1] . '[' . $param[0] . '][all]" id="' . $param[0] . '[all]" />  All<br />';
	}

	foreach ($roles as $key => $value) {
		if ($val[$key] === 'on') {
			echo '<input type="checkbox" name="' . $param[1] . '[' . $param[0] . '][' . $key . ']" id="' . $param[0] . '[' . $key . ']" checked />  ' . $value . '<br />';
		}
		else {
			echo '<input type="checkbox" name="' . $param[1] . '[' . $param[0] . '][' . $key . ']" id="' . $param[0] . '[' . $key . ']" />  ' . $value . '<br />';
		}
	}
}

Adding Custom User Profile Fields

As covered in the first tutorial of this series, users can have additional data associated with them in the form of key/value pairs. We covered the functions to add, update and remove users' metadata in the second tutorial. In this part, we'll see how to add a section to each user profile page, and update the user metadata accordingly.

Step 1 Hooking to the User Profile

WordPress provides four actions to hook to the user profile page. Two actions to add new fields to the edit page; and two other actions to handle the HTTP POST request. The difference between the "show_user_profile" action and "edit_user_profile" action is that the latter passes a WP_User object for the user being edited. However, the difference between the two other actions is not clear.

/**
 * User Metabox hooks
 */
private function metabox_user() {
	// Display the metabox
	add_action('show_user_profile', array(&$this, 'display_metabox'));
	add_action('edit_user_profile', array(&$this, 'display_metabox'));

	// Save update
	add_action('personal_options_update', array(&$this, 'update_metabox'));
	add_action('edit_user_profile_update', array(&$this, 'update_metabox'));
}

Step 2 Displaying the Custom Field

Unlike the Settings API, there are no restrictions or requirements to the HTML code the function outputs. WordPress doesn't do the saving of the metadata, so you are free to handle it as you wish.

/**
 * Display the custom field
 *
 * @param object $user
 */
public function display_metabox($user) {
	$user_meta = get_user_meta($user->ID, 'wptuts_client', true);
	if ($user_meta) {
		$checked = 'checked';
	}
	else {
		$checked = '';
	}

	print <<<form
<h3>Wptuts+ Client</h3>
<table class="form-table">
<tr>
<th><label for="wptuts_client">Enable Client Access</label></th>
<td><input type="checkbox" name="wptuts_client" id="wptuts_client" $checked/> Enable Access to the Wptuts+ Plugin Client Dashboard</td>
</tr>
</table>
form;
}

Step 3 Saving the Custom User Fields

As mentioned earlier, we need to handle the saving on a different function. This function is called when the user presses the "Update Profile" button and the HTML form is submitted in a POST request.

/**
 * Update the user Meta-data
 *
 * @param integer $user_id
 */
public function update_metabox($user_id) {
	if (isset($_POST['wptuts_client']) && $_POST['wptuts_client'] === 'on') {
		$checked = true;
	}
	else {
		$checked = false;
	}
	update_user_meta($user_id, 'wptuts_client', $checked);
}

Updating the Class Initialization

Finally, we need to update our class. In the previous tutorial, our class is constructed with three parameters. We don't need these parameters now; and our function should fetch them itself from the data saved by the interfaces.

We have two sources of data to fetch: the "wptuts_settings" option and the user metadata. Hopefully, fetching the metadata was made pretty easy with the function "get_users()" which returns exactly what we need (an array of user IDs) by simply specifying the meta key and value that the user should have.

/**
 * Set the permission entities
 *
 * @param boolean $all
 * @param array $roles
 * @param array $users
 */
private function set_entities() {
	$settings = get_option('wptuts_settings');
	$roles = $settings['client_roles'];

	// ALL rule
	if (isset($roles['all']) && $roles['all'] === 'on') {
		$this->all = true;
	}
	else {
		$this->all = false;
	}

	// Roles rule
	$this->roles = $roles;
	unset($this->roles['all']);

	// Users rule
	$this->users = get_users(array('meta_key' => 'wptuts_client', 'meta_value' => true, 'fields' => 'ID'));
}

Conclusion

That's it! Now we have an interface in the WordPress admin for roles and capabilities. Let us know in the comments below what your thoughts are on roles and capabilities, and what features you might add to the class and interface we've created in this series.

Related Posts
  • Code
    Creative Coding
    Using WordPress for Web Application Development: WP_User_QueryApplication foundation 400
    In this series, we've been taking a look at how WordPress can be used to development web applications much like a number of different frameworks and other tools that are available. Starting in the last article, we began looking at the different options that we have as it relates to querying the WordPress data. First, we reviewed WP_Query.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: The Footer FileCreating wordpress theme from html 400
    In this series, you've been learning how to create a WordPress theme form static HTML. Up to this point, you have: prepared your markup for WordPress converted your HTML to PHP and split your file into template files edited the stylesheet and uploaded your theme to WordPress added a loop to your index file added meta tags, the wp_head hook and the site title and description to your header file added a navigation menu added widget areas to the header and sidebar. Read More…
  • Code
    Theme Development
    Creating a WordPress Theme from Static HTML - Adding WidgetsCreating wordpress theme from html 400
    In this series, you've learned how to convert a static HTML file to a WordPress theme and edit the header file. So far you've: prepared your markup for WordPress converted your HTML to PHP and split your file into template files edited the stylesheet and uploaded your theme to WordPress added a loop to your index file added meta tags, the wp_head hook and the site title and description to your header file added a navigation menu. Read More…
  • Code
    Creative Coding
    Using WordPress For Web Application Development: Features: User ManagementApplication foundation 400
    Throughout this series, we've been taking a look at how WordPress can serve as a foundation for web application development. The thing is, up to this point, we haven't really taken a look at the features of WordPress that really contribute to building web applications. Instead, we've spent time looking at how WordPress serves as a foundation rather than a framework, and we've looked at how WordPress is organized in comparison to many of the modern frameworks that are available.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    Plugins
    How to Create a WordPress Avatar Management Plugin from Scratch: Getting StartedPreview
    Avatar Manager for WordPress is a sweet and simple plugin for storing avatars locally and more. Easily. Enhance your WordPress website by letting your users choose between using Gravatar or a self-hosted avatar image right from their profile screen. Improved workflow, on-demand image generation and custom user permissions under a native interface. Say hello to the Avatar Manager plugin.Read More…