Tag Archives: capabilities

register_activation_hook()

I’m creating custom post type in a plugin for the first time. So far, it’s been done directly in the child theme. Not the best place as functionality should be separate from display.

The first thing was to copy, edit and paste one of the register_post_type() calls I had written before. Right away something was strange. The CPT showed up on my development site, but not on a blank install. After much commenting out of various lines, I found that the problem lay with the ‘capability_type’ argument.

My development site is multisite, and it looks like network admins have much more capabilities than normal site admins, or perhaps it was the role management plugin magically granting it rights. I looked into the code for the role management plugin (Members by Justin Tadlock) and discovered that it added some extra capabilities upon plugin activation. Sounds like just what I needed.


register_activation_hook( __FILE__, 'mbpc_feba_cpt_install' );

// Start by giving the administrator role access to the CPT
function prefix_cpt_install() {
	/* Get the administrator role. */
	$role =& get_role( 'administrator' );

	/* If the administrator role exists, add required capabilities for the plugin. */
	if ( !empty( $role ) ) {
		/* Role management capabilities. */
		$role->add_cap( 'publish_cptname' );
		$role->add_cap( 'create_cptname' );
		$role->add_cap( 'delete_cptname' );
		$role->add_cap( 'edit_cptname' );
	}

}

I’ve edited some of the names used. When you’re writing your own, remember to prefix your functions so they’ll be unique, and of course replace ‘cptname’ with a meaningful name.

Unfortunately, the code above did not work for me. It looked like the activation function was not being called. Putting echo statements inside didn’t do anything, and even putting die() inside did nothing.

When there’s a problem, start with the Codex. The page for register_activation_hook() had line near the bottom referencing a support forum thread. Turns out that ‘echo’ really doesn’t work, and the way to check if the activation hook is being called is to use exit().

Another user pointed out that __FILE__ doesn’t work when the plugin directory is only symlinked. That’s exactly what I’m doing! The solution is to pass it the path to the symlink.

register_activation_hook( WP_PLUGIN_DIR . '/plugin-name/plugin-name.php', 'prefix_cpt_install' );

And now the CPT shows up in the admin menus! wp_user_roles in the options table also has the new capabilities added by the activation function.

Roles and Capabilities for Custom Post Types

WordPress access rights are controlled by Roles and Capabilities. To perform an action, your user role must have that capability. For example, to edit posts, your role must have edit_posts assigned to it.

Custom Taxonomies

Strangely, while managing terms for custom taxonomies requires manage_categories, this does not give the user the right to assign terms to the post. To allow that, add

'capabilities' => array('assign_terms' => 'edit_sermons')

to the arguments array of register_taxonomy(). Replace the word “sermons” with whatever you want to name this capability. Naming it edit_sermons means that the user who can edit sermon custom post types will also be able to assign terms belonging to this taxonomy.

Custom Post Types

Posts and pages have built in capabilities for editing, adding, publishing etc etc. To restrict custom post types, it’s necessary to assign them a new bunch of capabilities. Do this by adding the following code to the array of arguments.

'capability_type' => 'sermon',
'map_meta_cap' => true

The map_meta_cap key is necessary so that edit_sermons, delete_sermons and add_sermons will work as expected.

This is explained in Justin Tadlock’s article, but he had to do it manually then.

Assign Capabilities

Use the Members plugin to create roles and assign capabilities. When assigning capabilities, give edit_{capability_type}, publish_{capability_type}, but add an ‘s’ after that (plural form).

Members Plugin

I needed to figure out how to control who could add the different types of content to the site. The information in the WordPress codex on Roles and Capabilities isn’t too complete at the moment. It took a few readings to understand the system, but there was still not much clue on how to write code to customize it.

After trying a couple of different plugins, I finally found that the Members plugin by Justin Tadlock does what I want. This plugin can be used to manage roles and then assign them capabilities. It can also do other things like limit content from certain users, but I only want to control the types of content which the different roles can post.

My plan is to have a blogger role who will only post normal WordPress posts. These will appear on the blog page. Another role will take on the role of content manager. This role will be given control over the sermons and newsletters, but not the blog posts. The primary intention of all this is to make the admin interface less complex for the end users and only show them the things they can edit.

The blogger role is currently fulfilled by the default author role. By adding the ‘capability_type’ key to the custom post types, the default author can no longer see them.

Using the plugin, it was a simple task to add the role of content manager. I then gave it capabilities to edit and publish sermons and newsletters. The necessary capabilities are edit_sermons, edit_others_sermons, edit_published_sermons, publish_sermons, delete_sermons, delete_others_sermons for sermons. Replace ‘sermons’ with ‘newsletters’ and all all the capabilities for control over newsletters.

It is also necessary to grant manage_categories so category and taxonomy terms can be added and managed. To allow the role to assign terms in custom taxonomies, the key-value pair 'capabilities' => array('assign_terms' => 'edit_sermons') is needed when registering the custom taxonomy. Once again, replace ‘sermon’ with whatever capability_type you want.

To allow media to be managed, the edit_posts and *_posts capabilities also had to be added. * is a wildcard for all the other functions. This actually allows the content manager control over the blogger’s posts, but the problem is mitigated somewhat by hiding the posts menu from the interface.

While the author role currently fulfills the blogger role, it would be better to separate them. The default author role will then be given the combined capabilities of church_cm and blogger.