Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
  1. Code
  2. WordPress

Create a Simple CRM in WordPress: Using Custom Capabilities

This post is part of a series called Create a Simple CRM in WordPress.
Create a Simple CRM in WordPress: Restricting / Hiding Menu Items

We’ve been looking at how to create a simple CRM system in WordPress. In the last part of this series, we explored how to use Roles to restrict User access to parts of the WordPress Administration interface.

Today we’ll cover how to restrict access to only the Contacts Custom Post Type using Custom Capabilities.

Custom Capabilities

Whilst we previously reduced the level of access our WordPress Users have, by assigning them to an Editor or Author role, Users are still able to manage Posts and Comments. Neither of these functions are useful to us, so we need to restrict access further, allowing assigned Users to only have access to the Contacts Custom Post Type.

We can do this by:

  1. registering Custom Capabilities on our Custom Post Type
  2. creating a new WordPress User Role, assigning just our new custom capabilities to that Role
  3. creating / editing WordPress Users, assigning them to the new Contacts Role

Registering Custom Capabilities on Our Custom Post Type

Registering custom capabilities allows us to later define which WordPress Role(s) have access to these capabilities—for example, whether an Author can create a new Contact.

Let’s edit our plugin file’s register_post_type() function call, replacing capability_type => 'post' with the following:

Our register_post_type() function should now look like:

Here, two things happen:

  1. We’ve defined our own capabilities using the capabilities argument, mapping them to their Post equivalents. This ensures WordPress understands precisely what the capabilities mean (i.e. edit_contact behaves in the same way as the edit_post capability, except that it’s for our Contacts Custom Post Type).
  2. We’ve told WordPress to map the above capabilities to WordPress’s primitive capabilities, using map_meta_cap, so they are enforced.

Reload the WordPress Administration as any User, and you’ll see our Contacts Custom Post Type has disappeared from the WordPress Administration Menu:

Contacts Custom Post Type missing

This happened because we now need to tell WordPress which Roles have our new Contacts Capabilities (edit_contact, edit_contacts, etc).

Creating a New WordPress User Role, Assigning Just Our New Custom Capabilities to It

Using add_role(), we can create a new WordPress User Role and assign our Contacts Capabilities to it. The role is stored in the WordPress Options data, so we only need to make this function call once.

To do this, add the following function below the end of the __construct() function in our plugin:

This function will add a new role called CRM to WordPress. Users assigned to this Role will only have access to the Contacts Capabilities. Therefore, they will only have access to the Contacts Custom Post Type.

Notice we also assign the read capability to this Role. This is required to allow Users to edit their Profile (Name, Password, etc). We need to allow Users to do this, because when they log in, WordPress will automatically redirect them to the Profile screen.

If we didn’t assign the read capability, this is what would happen when the User logs in:

Error message when read capability is not assigned to a Role

To run our plugin_activation() function once, let’s add the following code to the end of our plugin file:

This tells WordPress that, on plugin activation, it needs to call the plugin_activation() function inside our WPTutsCRM class.

Creating / Editing WordPress Users, Assigning Them to the New Contacts Role

Next, deactivate and re-activate your Plugin, and then navigate to Users > Add New in the WordPress Administration interface.

If everything has worked successfully, you will see the new CRM role appear on the dropdown list:

Our new WordPress Role

Let’s go ahead and create a new User called crm, and log in as that new User. We should now see our Contacts, with the Dashboard and Profile as the only other menu options:

Assigning Custom Capabilities to Other Roles

If we log out and log back in as a WordPress Administrator, Editor or Author, you’ll notice that the Contacts Custom Post Type is still missing from the WordPress Administration Menu:

This is because we have only assigned the CRM Role our Contact Custom Post Type’s Capabilities. Therefore, all other User Roles still do not have access to this Post Type.

To fix this, let’s assign the Custom Capabilities to the Administrator and Editor Roles by adding the following code to the end of the plugin_activation() function:

Here, we iterate through the Roles we want to assign Custom Capabilities to, checking the Role exists. If it does, we then iterate through the Custom Capabilities we defined earlier, adding them to the Role.

You’ll notice we haven’t added any Custom Capabilities to the Author Role; this is because we don’t want to assign all of the Capabilities, as the Author Role traditionally only permits write access to that User’s own Posts.

Let’s continue building our plugin_activation() function by adding some Capabilities for the Author Role:

Our whole function should now look like:

Logging in as an Administrator, Editor or Author will now show the Contacts option in the WordPress Administration Menu:

Cleaning Up Our Roles

If the WordPress Administrator deactivates our plugin, the CRM Role will remain in WordPress. However, given that no other plugin or part of WordPress uses this Role, it’s redundant—so we need to make sure the CRM Role is removed when our plugin is deactivated.

To do this, add the following function below the plugin_activation() function:

In the same way we used the register_activation_hook() function when our plugin activated, we can use the register_deactivation_hook() when our plugin deactivates. Let’s add the following below the register_activation_hook call:

When our plugin is deactivated, our CRM Role will no longer be available.


We’ve successfully created a simple CRM system in WordPress, exploring the use of Custom Post Types, Post Meta Fields and third party plugin integration to store information about our customers and prospects.

This tutorial has also covered some of the more advanced aspects of WordPress, by displaying Advanced Custom Fields data through WP_List_Table Columns, filtering our Post Query to search our Advanced Custom Fields data, and managing User access through Roles and Capabilities to restrict access to just our CRM system.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.