因此,我正在构建一个具有3个不同自定义角色的系统-Admins, Providers, 和Users.
提供商可以访问用户。php或列表用户页面。但是,他们应该无法查看/编辑/访问Admins, 或其他Providers. 他们应该能够清楚地看到/编辑自己,并看到/编辑所有Users.
我的问题是,如何防止提供商看到此页面上的“ALL”或“Admins”选项卡/链接?我如何确保他们只看到自己Users?
为了清楚地说明我正在努力实现的目标,包括以下图片:
我在pre_user_query
钩这是我的代码的简化版本。
阅读评论!
// alter what shows on the list users page by role
function abc_pre_user_query($user_search) {
// first off, I can\'t even get users because \'get_users\' causes this error:
// Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes)
/*
$args = array(
\'role\' => \'abc_admin\',
\'fields\' => \'all\',
);
$users = get_users( $args );
*/
// So for testing, I just manually create a list of user IDs to exclude
// this would be IDs of all abc_admins and providers (besides the current provider)
$users = array(\'18\', \'19\', \'38\');
/************************
METHOD 1 - SQL
************************/
$user_search->query_where = str_replace(\'WHERE 1=1\',
"WHERE 1=1 AND
(wp_usermeta.meta_key = \'wp_capabilities\' AND wp_usermeta.meta_value NOT LIKE \'%abc_admin%\') AND
((wp_usermeta.meta_key = \'wp_capabilities\' AND wp_usermeta.meta_value NOT LIKE \'%provider%\') OR wp_users.ID = " . $current_uid . ")",
$user_search->query_where);
// This works! But when the user is on "ALL", it shows zero users and shows this error:
// [Unknown column \'wp_usermeta.meta_key\' in \'where clause\']
// So I was thinking of forcing user.php to redirect to users.php?role=provider, but this seems hacky
// maybe I am on the right path here and am missing something?
/************************
METHOD 2 - Query vars
************************/
// Here I try various ways to alter the $user_search WP User Query Object
// Either change \'exclude\' to my $users array, or change \'role\' to only grab the user role
// ... to no avail
//$user_search::set(\'exclude\', $users); // Deprecated: Non-static method WP_User_Query::set() should not be called statically
//$user_search::set(\'role\', \'user\'); // Deprecated: Non-static method WP_User_Query::set() should not be called statically
//$user_search->query_vars[\'exclude\'] = $users; // does nothing
//$user_search->query_vars[\'role\'] = \'user\'; // does nothing
// I can print $user_search here, and can confirm the lines that say "does nothing"
// actually change in query_vars, but on the users page NOTHING CHANGES
// Maybe using ::set is the correct way and I am calling it incorrectly?
}
add_action(\'pre_user_query\', \'abc_pre_user_query\');
如你所见,我尝试了两种主要方法来实现这一点。我无法想象这是第一次有人不得不这样做。
顺便说一下,我正在使用用户角色编辑器。但是,没有像list_abc_admins
或list_other_providers
或者别的什么。只有list_users
, 提供者拥有的,以便角色可以查看站点上的所有帐户,这正是我的问题。
也许首选的方法与创建更具体的功能并以某种方式实现这些功能有关?我觉得修改用户查询更有效,但我想我可能错了。
我可以发布$user_search
变量或其他任何需要的变量。
提前感谢!
最合适的回答,由SO网友:phatskat 整理而成
方法1,SQL关于SQL的注释
[Unknown column \'wp_usermeta.meta_key\' in \'where clause\']
通过将其添加到
JOIN
查询部分:
JOIN wp_usermeta ON ( wp_usermeta.user_id = wp_users.ID )
您可以检查联接的值,如果
false === strpos( \'wp_usermeta\', $joins )
, 自己添加。
当获得所有用户时,我猜测WordPress不会加入wp_usermeta
因为它不需要处理功能。
方法2,更改查询对象,可能使用::set是正确的方法,而我调用它的方式不正确?
答对 了你在打电话::set
静态地,当它应该作为对象的方法调用时:
$user_search->set(\'exclude\', $users);
$user_search->set(\'role\', \'user\');
在PHP中,
::
表示作为类定义一部分的静态方法调用或函数,而
->
用于对属于类实例一部分的方法进行操作。您经常看到这个符号用于谈论方法名称
SomeClass::Method()
, 这可能会让人困惑-这并不是说你使用
::Method
调用该方法,但它在视觉上试图将其表示为该类的方法。通常,在实例化时,您会执行以下操作:
$obj = new SomeClass();
$obj->Method();
除非方法声明为静态,在这种情况下
$obj::Method();
是正确的。
回答不好,您可以使用load-(page)
挂钩和CSS。不幸的是,对于我找到的过滤器,似乎还没有一个好的方法来实现这一点。
要使用CSS执行此操作,可以执行以下操作:
add_action( \'load-users.php\', function(){
if ( can_see_editors() ) {
return;
}
echo <<<HTML
<style>
#wpbody ul.subsubsub li.editor {
display: none;
}
</style>
HTML;
});
替换中的第一个方法
if
对于可以查看TDF管理员的用户,请使用您的逻辑。如果不能,它会继续向下将CSS呈现到隐藏元素的页面-在您的情况下,突出显示“TDF Admin”过滤器并检查它以找到它的CSS类名(与
li.editor
).
这个修复程序非常脆弱-任何人都可以检查页面并显示链接,没有任何东西可以阻止他们更改URL以指向URL过滤TDF管理员。