web-dev-qa-db-ja.com

Add_submenu_pageにフックする

ページにmanage_options機能を使用しているプラ​​グインに出会ったことがありますか?本当にそうする必要はありませんか?まあ、私はそれに遭遇しました。

これはadd_submenu_pageにフックすることについての一般的な質問であるかもしれません、それで私のユースケースだけに特定ではありません。

単にadd_dashboard_pageのラッパーであるadd_submenu_pageを見ました。

function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
    global $submenu;
    global $menu;
    global $_wp_real_parent_file;
    global $_wp_submenu_nopriv;
    global $_registered_pages;
    global $_parent_pages;

    $menu_slug = plugin_basename( $menu_slug );
    $parent_slug = plugin_basename( $parent_slug);

    if ( isset( $_wp_real_parent_file[$parent_slug] ) )
        $parent_slug = $_wp_real_parent_file[$parent_slug];

    if ( !current_user_can( $capability ) ) {
        $_wp_submenu_nopriv[$parent_slug][$menu_slug] = true;
        return false;
    }

    // If the parent doesn't already have a submenu, add a link to the parent
    // as the first item in the submenu. If the submenu file is the same as the
    // parent file someone is trying to link back to the parent manually. In
    // this case, don't automatically add a link back to avoid duplication.
    if (!isset( $submenu[$parent_slug] ) && $menu_slug != $parent_slug ) {
        foreach ( (array)$menu as $parent_menu ) {
            if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) )
                $submenu[$parent_slug][] = $parent_menu;
        }
    }

    $submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );

    $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug);
    if (!empty ( $function ) && !empty ( $hookname ))
        add_action( $hookname, $function );

    $_registered_pages[$hookname] = true;
    // backwards-compatibility for plugins using add_management page. See wp-admin/admin.php for redirect from edit.php to tools.php
    if ( 'tools.php' == $parent_slug )
        $_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true;

    // No parent as top level
    $_parent_pages[$menu_slug] = $parent_slug;

    return $hookname;
}

実は、既存のダッシュボードページを使って機能を変更することができるものは何もないようです。ですから、 remove_submenu_page を使った方がよいかどうかを判断してから、同じサブメニューを再宣言しようとします。私が気をつける必要があることがあることを知っています(そのページに使用されている表示機能に、その機能をさらにチェックしたり、サイトにとって重要なものを表示したりするものがある場合)。私が物事を過度に複雑にしないように、これらの上で2番目の目のペアを持つことは常に役に立ちます。皆さんありがとう!

更新

@toschoと@userabuserの両方に感謝します。

function wpse_71303_change_menu_cap()
{
    global $submenu;
    foreach ($submenu['index.php'] as $dashboard => $key) {
        if ($key[0] == 'Analytics360°') {
            $submenu['index.php'][$dashboard][1] = 'analytics';
        }
    }
}
add_action( 'admin_head', 'wpse_71303_change_menu_cap' );

私がprint_r($submenu) I do see the new capability - but I still can't access the menu item under the client role I created (with theanalytics_360`ケーパビリティを実行するなら(作成するためにMembersプラグインを使いました)。おそらく発砲が遅すぎる?確かに少し変です。いつもありがとう!

Updateのコードは、これに遭遇したすべての人に有効です。それは私に問題を与えているadd_dashboard_page()の周りの不要なチェックでした。

2
Zach

メニューがレンダリングされる前の最後のアクションであるadmin_headにフックし、グローバルな$menuを変更します。

add_action( 'admin_head', 'wpse_71303_change_menu_cap' );

/**
 * Change the capability to access an admin menu item.
 *
 * @wp-hook admin_head
 * @return void
 */
function wpse_71303_change_menu_cap()
{
    global $menu;

    foreach ( $menu as $key => $item )
    {
        // Find menu by name
        if ( 'Tools' === $item[0] ) // default cap: 'edit_posts'
        {
            $menu[ $key ][1] = 'new_capability';
        }
    }
}
4
fuxia