我偶然发现了一些关于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会中断管理循环的其余部分。
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
在注册帖子类型时给出,不一定是因为用户拥有的功能。我认为我在代码中看到的是,更高级别的功能在protected
和private
发布的内容比注册为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);