使用自定义用户角色访问时,get_post()不起作用

时间:2018-11-21 作者:Tony Djukic

我偶然发现了一些关于WP“get\\u posts”功能的文档,但似乎找不到任何文档。

我有一个web应用程序,它有多个自定义帖子类型和多个自定义用户角色。出于各种原因,它们都是必要的。组织中不同的用户类型需要看到不同的内容,并能够编辑自定义帖子类型的不同方面。

在自定义帖子类型编辑屏幕中,我有显示用户提供的数据的元盒,但是,具有后端访问权限的用户使用不同的自定义用户角色,需要能够更正或修改用户提供的数据,或者手动创建条目。

我使用以下“get\\u posts()”方法根据其他自定义帖子类型的条目生成下拉列表:

<select name="mwss_session">
    <option value="">Please select a Session</option>
    <?php
        $get_sessions = get_posts( array(
            \'post_type\'         => \'seasonal_sessions\',
            \'post_status\'       => \'publish\',
            \'posts_per_page\'    => -1,
            \'meta_key\'          => \'mwss_session_status\',
            \'meta_value\'        => \'true\',
            \'meta_compare\'      => \'=\'
        ) );
        $selected_session = $mwss_session;
        foreach( $get_sessions as $active_session ) {
            $session_name = get_the_title( $active_session->ID );
            echo \'<option value="\' . $session_name . \'"\';
            if( $selected_session === $session_name ){ echo \'selected\'; }
            echo \'>\' . $session_name . \'</option>\';
        }
    ?>
</select>
它按你的预期工作。您访问编辑屏幕,下拉列表中填充了“会话”,其“状态”设置为“true”。这个get\\u posts()方法也适用于前端,无论是否登录。

但是,在访问编辑时。使用我创建的自定义用户角色之一、此下拉列表和其他使用相同方法的帖子类型的php屏幕都无法返回结果。

以下是一个自定义用户角色功能的示例:

$result = add_role(
    \'mwss_sitesuper\', __(\'Site Supervisor\'),
    array(
        //WordPress Capabilities
        \'level_9\'                       => false,
        \'level_8\'                       => true,
        \'level_7\'                       => true,
        \'level_6\'                       => true,
        \'level_5\'                       => true,
        \'level_4\'                       => true,
        \'level_3\'                       => true,
        \'level_2\'                       => true,
        \'level_1\'                       => true,
        \'level_0\'                       => true,
        \'read\'                          => true,
        \'read_private_pages\'            => true,
        \'read_private_posts\'            => true,
        \'create_posts\'                  => true,
        \'publish_posts\'                 => true,
        \'edit_users\'                    => true,
        \'edit_posts\'                    => true,
        \'edit_pages\'                    => true,
        \'edit_published_posts\'          => true,
        \'edit_published_pages\'          => true,
        \'edit_private_pages\'            => true,
        \'edit_private_posts\'            => true,
        \'edit_others_posts\'             => true,
        \'edit_others_pages\'             => true,
        \'publish_posts\'                 => true,
        \'publish_pages\'                 => true,
        \'delete_posts\'                  => true,
        \'delete_pages\'                  => true,
        \'delete_private_pages\'          => true,
        \'delete_private_posts\'          => true,
        \'delete_published_pages\'        => true,
        \'delete_published_posts\'        => true,
        \'delete_others_posts\'           => true,
        \'delete_others_pages\'           => true,
        \'manage_options\'                => false,
        \'manage_categories\'             => false,
        \'manage_links\'                  => false,
        \'moderate_comments\'             => true,
        \'unfiltered_html\'               => false,
        \'upload_files\'                  => false,
        \'export\'                        => false,
        \'import\'                        => false,
        \'list_users\'                    => true,
        \'edit_themes\'                   => false,
        \'install_plugins\'               => false,
        \'update_plugin\'                 => false,
        \'update_core\'                   => false
    )
);
知道为什么get\\u posts()只适用于后端的管理员或编辑器角色,而适用于前端的所有用户角色吗?

Update: 在深入研究了功能之后,我得出结论,这与功能无关。在前端,无论用户的能力或角色如何,相同的“get\\u posts”函数都会返回结果。因此,如果一个用户角色的级别低至subscriber,或者如果所有自定义用户角色都能够查看前端上填充了预期“会话”的下拉列表,那么理论上他们就有能力这样做,对吗?还是我遗漏了什么?该问题似乎与CPT内的代谢箱无关。如果我使用WP\\u Query,它会工作,但WP\\u Query会中断管理循环的其余部分。

2 个回复
SO网友:Mort 1305

“我也有这个问题,”托尼·朱基奇说道。我有一个管理员用户,可以查看两个自定义帖子类型的帖子。我有两个订户用户,每个用户只能看到对方的帖子。以下是我用来(显然不是)获取所有帖子的方法:

get_posts(array(
    \'numberposts\'       => -1,
    \'post_type\'         => \'my-cpt\',
    \'post_status\'       => get_post_stati(),
))
在过去几天的每一天中,我都花了几个小时寻找一个解决方案,之后,我遇到了你(1.5岁)未回答的问题。没有其他选择,我跟踪了代码。这是我的作品。。。

1.) 根据文件get_posts() method 返回的结果WP_Query->query() 传递了一系列参数(这在考虑当前问题时并不重要)。

2.) 文件上说WP_Query->query() method 是一个非常简单的包装器,用于初始化WP_Query 返回的结果之前的WP_Query->get_posts().

3.) 接下来WP_Query->get_posts() method 被调用。在第2434行附近,read\\u post和edit\\u post功能开始发挥作用。请注意,这不是自定义post类型的read\\u CPT或edit\\u CPT原语,而是post类型的原语。然后在current_user_can 呼叫(请参阅第3087、3096、3105和3111行)。换句话说,如果您的用户没有read\\u post和edit\\u post功能,则在current_user_can() 结果中将不包括调用。这与自定义功能的目的完全相反:所检查的功能应该是读取CPT或编辑CPT,因此这显然是编码人员的某种意外。毕竟,授予这些权限可能会允许用户编辑帖子(以及自定义帖子类型)。

NOTE: 用户能够在前端阅读的原因更多是因为public=TRUE 在注册帖子类型时给出,不一定是因为用户拥有的功能。我认为我在代码中看到的是,更高级别的功能在protectedprivate 发布的内容比注册为public.

LONG-TERM FIX: WordPress应该在执行检查以确定是否正在查询CPT之后定义这两个变量(第2434行和第2435行):显然,这在编码中被忽略了。应该在第2437-2443行的后续检查中设置这些表示能力的变量。即,该代码块应为:

if ( ! empty( $post_type_object ) ) {
    $edit_cap = $post_type_object->cap->edit_post;
    $read_cap = $post_type_object->cap->read_post;
    $edit_others_cap  = $post_type_object->cap->edit_others_posts;
    $read_private_cap = $post_type_object->cap->read_private_posts;
} else {
    $edit_cap = \'edit_\'. $post_type_cap;
    $read_cap = \'read_\'. $post_type_cap;
    $edit_others_cap  = \'edit_others_\' . $post_type_cap . \'s\';
    $read_private_cap = \'read_private_\' . $post_type_cap . \'s\';
}
SHORT-TERM FIX: 在这一切之后,我想出了以下临时解决方案。这个user_has_cap filter 可以在早期挂钩中实现。将对象的ID传入挂钩$args[2] 钩子的ID,可以检查它是否是具有自定义post类型的对象的ID。如果是,则user_can method 可以返回该自定义功能。整个事情可能是这样的:

add_filter(\'user_has_cap\' function($allcaps, $caps, $args, $user){
    $pt = get_post_type($args[2]);
    if(ctype_digit($args[2])
    && $pt !== FALSE
    ) {
        $pt_obj = get_post_type_object($pt);
        if(!is_null($pt_obj)
        && !$pt_obj->_builtin
        ) {
            foreach($caps as $cap) {
                $type = substr($cap, strrpos($cap, \'_\')+1);
                if($type === \'post\'
                || $type === \'posts\'
                ) {
                    // $pt_obj->cap set by get_post_type_capabilities()
                    $allcaps[$cap] = user_can($user, $pt_obj->cap->$cap, $args);
                }
            }
        }
    }
    return $allcaps;
}, 0, 4);

SO网友:socki03

尝试添加read_seasonal_sessions 并将其设置为true。每个新CPT都有7个新功能可添加到用户角色中。(参见capability_type 在…上register_post_type())

添加map_meta_cap 设置为register\\u post\\u type函数(如果有),并将其设置为true。(参见map_meta_cap 在下面register_post_type())

默认情况下,map_meta_capnull, 因此,我认为这并不是将post功能直接映射到您的CPT。

结束

相关推荐

如何让`wp-list-table`显示我在Custom-Post中的`Custom-Fields`

一切都好吗<我需要wp-list-table 也要显示custom-fields 在每个custom-post 我有,但我不知道如何做到这一点,在这幅图中,它显示了带有字段的表格:Title, Author and Publication Date: 我想要的是能够选择custom-fields 将出现,例如以下示例Title, Carta, Naipe, Author, and Date of Publication: