Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I develop plugin with custom post type (cpt) who has some custom capabilities. I add those capabilities to the roles (according to the current caps, see code below) on plugin activation. That won't work, so I decided to add a init hook, who always fires and add only the capabilities if needed.
So far so good: the capabilities are assigned to the roles on activation. But the menu-item of the custom post type is not visible on activation (that is the plugins.php screen with the message plugin activated). On the next request (page refresh or a click on any wp-admin link) is the menu-item visible.

Does anybody know why the custom posttype menu-item is not visible, direct after activation? And how could it be solved?

posttype-cpt.php

<?php
Class PosttypeCpt {
    function __construct() {
        add_action('init', array(&$this, 'add_posttype'));
    }

    function add_posttype() {
        register_posttype('cpt', array( ... , 'capability_type' => 'cpt_cap',
            'map_meta_cap' => true, ...);
    }
}

plugin.php

class MyPlugin {
    function __construct() {
        // won't work: register_activation_hook(__FILE__, array(&$this, 'assing_capabilities')); 
        register_deactivation_hook(__FILE__, array(&$this,'remove_capabilities'));
        add_action('init',array(&$this, 'assign_capabilities'), 98); // priority to 98, so after the register posttype call in posttype-cpt.php
    }

    /**
     * Assigns capabilities to the current roles.
     * Called on plugin activation
     */
    function assign_capabilities() {
        $admin = get_role('administrator');
        if (!$admin->has_cap('edit_cpt_cap')) { // this test doesn't work, but that doesn't matter now.
            echo 'Do caps!'; // for debugging
            global $wp_roles;
            if ( ! isset( $wp_roles ) )
                $wp_roles = new WP_Roles();
            $posttype_cpt = get_post_type_object('cpt');
            //print_r($posttype_cpt);
            // Add cpt caps according to the current caps
            // Example: role has edit_post (and is granted), then the role edit_cpt_cap is added.
            foreach ($wp_roles->role_objects as $name => $role) {
                foreach ($role->capabilities as $cap => $grand) {
                    if (isset($posttype_cpt->cap->$cap) && $grand) {
                        $role->add_cap($posttype_cpt->cap->$cap);
                    }
                }
            }
        }
    }

    /**
     * Removes the capabilities from the roles
     * Called on plugin deactivation
     */
    public function remove_capabilities() {
        global $wp_roles;
        if ( ! isset( $wp_roles ) )
            $wp_roles = new WP_Roles();
        $posttype_epa = get_post_type_object(EPA_PostType::POSTTYPE_NAME);
        $epa_caps = array_values(get_object_vars(($posttype_epa->cap)));
        // remove epa caps
        foreach ($wp_roles->role_objects as $role) {
            foreach ($epa_caps as $cap) {
                if ('read' != $cap) // make shure that the read cap isn't removed.
                    $role->remove_cap($cap);
            }
        }
    }
}

$plugin = new MyPlugin();    
require_once 'posttype-cpt.php';

$posttype = new PosttypeCpt ();
share|improve this question
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.