02:讲透WordPress 菜单开发 - 权限控制与加载指定JS

承接上文,本节主要解决两个问题,

  • 菜单权限控制 – 仅限访问指定菜单和仅限指定人员访问菜单
  • 指定菜单页加载 CSS 和 JS

问题

本节围绕以下两个常见问题进行展开

权限控制

虽然默认的权限控制已经好用,但有时,我们希望只有指定 ID 的用户才能访问菜单。

比如,在我开发退款插件时,为了控制退款员工的权限,我只让他们访问 退款 菜单,其他菜单都拒绝访问,避免造成其他影响。

我可不希望退款员工删除网站首页,那就糟糕了
但是,只有管理员才有退款权限

加载 JS 和 CSS

默认的加载方式是在所有菜单页面上都加载 JS 和 CSS 资源,当加载的资源过多,会造成所有菜单页都会卡顿。

这点太不好了,该省省,该花花,这点浏览器资源,还是很有必要节省的。

通过在指定的菜单上才加载资源,可以有效的节省浏览器资源,提升后台页面访问速度。

后台一般是给管理者使用的,一般不太在乎页面加载速度,但是,这个是可以省的,我们还是节省下吧

流程

仅限指定用户可访问此菜单

获取用户ID

一般用户 ID 是设置选项给出的一个数组,这里我们进行简化,直接从用户列表中拿几个用户 ID 组成数组。

在用户列表中,选择你需要获取的用户,鼠标点击编辑按钮,

在 URL 中,注意这个 user_id 字段

  1. http://localhost:10004/wp-admin/user-edit.php?user_id=2&wp_http_referer=%2Fwp-admin%2Fusers.php

其中,user_id 后面的值,就是用户 ID 了,我们凭借这个值,来判断当前访问的用户。

我们将需要控制的用户 ID 组成数组

  1. $a = array(1,2,3,4,5,6);// 示例数组,存储若干用户ID

添加判断

还记得之前讲到,是如何创建顶级菜单的嘛?实例代码如下

  1. //创建一个菜单
  2. function vuespa_create_menu_page()
  3. {
  4. add_menu_page(
  5. 'VueSpa选项',// 此菜单对应页面上显示的标题
  6. 'VueSpa',// 要为此实际菜单项显示的文本
  7. 'administrator',// 哪种类型的用户可以看到此菜单
  8. 'vuespa_id',// 此菜单项的唯一ID(即段塞)
  9. 'vuespa_menu_page_display',// 呈现此页面的菜单时要调用的函数的名称
  10. 'dashicons-admin-customizer',//图标 - 默认图标
  11. '500.1',//位置
  12. );
  13. }// end vuespa_create_menu_page
  14. add_action('admin_menu','vuespa_create_menu_page');

我们对其添加一个判断,若当前访问菜单的人是指定的用户 ID,则输出空值,不显示菜单。

判断条件如下:

  1. if(
  2. current_user_can('administrator')
  3. && is_array($a)
  4. && in_array(get_current_user_id(), $a)
  5. ){}
  • 判断是否拥有管理员权限(可按需设置)
  • 并且,变量 $a 是否是数组
  • 并且,当前访问菜单的用户 ID 是否在数组 $a 中。

只有当前访问菜单的用户 ID 符合以上所有需求,才会展示菜单。

is_array() 用于类型检查,提升代码健壮性
示例

  1. //创建一个菜单
  2. function vuespa_create_menu_page()
  3. {
  4. //控制权限的员工 ID
  5. $a = array(1,2,3,4,5,6);// 示例数组,存储若干用户ID
  6. //权限判断
  7. if(
  8. current_user_can('administrator')
  9. && is_array($a)
  10. && in_array(get_current_user_id(), $a)
  11. ){
  12. add_menu_page(
  13. 'VueSpa选项',// 此菜单对应页面上显示的标题
  14. 'VueSpa',// 要为此实际菜单项显示的文本
  15. 'administrator',// 哪种类型的用户可以看到此菜单
  16. 'vuespa_id',// 此菜单项的唯一ID(即段塞)
  17. 'vuespa_menu_page_display',// 呈现此页面的菜单时要调用的函数的名称
  18. 'dashicons-admin-customizer',//图标 - 默认图标
  19. '500.1',//位置
  20. );
  21. }
  22. }// end vuespa_create_menu_page
  23. add_action('admin_menu','vuespa_create_menu_page');

现在,我们开发的这个菜单,即使是管理员来了,也只有指定的管理员才能访问。

指定用户仅限访问指定菜单

业务介绍:

在开发退款插件时,只有管理员才有退款权限,所以,只能给退款员工以管理员权限。

但是为了防止退款员工进行除退款外的其他操作,我们需要限制退款员工只能访问退款菜单。

流程

  1. 提供的变量是否是数组
  2. 当前访问的用户ID是否在提供数组中
  3. 获取当前链接的 page 字段,是否是指定菜单
  4. 如果是 admin-ajax.php 或 admin-post.php,则不拦截
  5. 符合以上全部信息,则拦截,并提供提示信息

对于第四点,如果我们当前在限制的菜单中,当我们要进行数据查询或保存数据等操作,会通过以上两个文件发出请求,这会因为不符合第3个条件而被拦截,这里做个例外。

示例代码

以下代码可供参考

  1. //权限管理
  2. add_action('admin_init','mqzj_restrict_access');
  3. function mqzj_restrict_access()
  4. {
  5. $user = wp_get_current_user();
  6. $a = array(1,2,3,4,5,6);// 示例数组,存储若干用户ID
  7. // 如果 $a 为空或为字符串,则将其赋值为空数组
  8. if(empty($a)|| is_string($a)){
  9. $a = array();
  10. }
  11. //是限定 ID
  12. if(in_array($user->ID, $a)){
  13. //在访问限定菜单
  14. if((isset($_GET['page'])&& $_GET['page']=='refund_querys')||(isset($_GET['page'])&& $_GET['page']=='npcink_orders_list')){
  15. return;
  16. } elseif (
  17. // 如果是 admin-ajax.php 或 admin-post.php,则不拦截
  18. preg_match('/^/wp-admin/(admin-ajax.php|admin-post.php)/', $_SERVER['PHP_SELF'])){
  19. return;
  20. }else{
  21. //跳转
  22. $adminPage = get_admin_url().'admin.php';
  23. $refundPage = get_admin_url().'index.php';
  24. $message ='
  25. 您暂无授权访问此页面,请联系管理员授权!
  26. <ul>
  27. <li>
  28. <a href="'.%20$adminPage%20.'?page=npcink_orders_list">订单管理</a>
  29. </li>
  30. <li>
  31. <a href="'.%20$refundPage%20.'?page=refund_querys">订单退款</a>
  32. </li>
  33. </ul>
  34. ';
  35. wp_die($message);
  36. exit;
  37. }
  38. }
  39. }

上面仅允许访问和提示的菜单如下

  1. https://www.npc.ink/wp-admin/index.php?page=refund_querys
  2. https://www.npc.ink/wp-admin/admin.php?page=npcink_orders_list&order_state=f

相信你已经掌握了其中的思路,留一个思考题,

你知道如何禁止访问评论菜单,比如这样的链接

  1. https://www.npc.ink/wp-admin/edit-comments.php

欢迎您在评论区中给出答案。

控制 JS 和 CSS 在菜单中的加载

加载资源

我们一般加载上述资源是这样写的

  1. function vuespa_load_vues($hook)
  2. {
  3. //版本号
  4. $ver ='66';
  5. //加载到页面顶部
  6. wp_enqueue_style('vite', plugin_dir_url(__FILE__).'vites/dist/index.css', array(), $ver,false);
  7. //加载到页面底部
  8. wp_enqueue_script('vite', plugin_dir_url(__FILE__).'vites/dist/index.js', array(), $ver,true);
  9. }
  10. //样式加载到后台
  11. add_action('admin_enqueue_scripts','vuespa_load_vues');

这样,我们就在所有后台的所有页面上,加载了上述资源

获取 $hook

还记得之前创建菜单时,每个菜单都有唯一的 slug 嘛?每个菜单页面也是有唯一的 $hook 的。

我们可以通过以下代码获取当前菜单的 $hook 值。

  1. function wpdocs_myselective_css_or_js( $hook ){
  2. echo '<h1 style="color: crimson;text-align: center;">'. esc_html( $hook ).'</h1>';
  3. }
  4. add_action('admin_enqueue_scripts','wpdocs_myselective_css_or_js');

打开我们需要获取的菜单页面,效果如下

进行判断

有了唯一值,剩下的交给判断就好了。

  1. function vuespa_load_vues($hook)
  2. {
  3. //判断当前页面是否是指定页面,是则继续加载
  4. if('toplevel_page_vuespa_id'!= $hook){
  5. return;
  6. }
  7. //版本号
  8. $ver ='53';
  9. //加载到页面顶部
  10. wp_enqueue_style('vite', plugin_dir_url(__FILE__).'vites/dist/index.css', array(), $ver,false);
  11. //加载到页面底部
  12. wp_enqueue_script('vite', plugin_dir_url(__FILE__).'vites/dist/index.js', array(), $ver,true);
  13. }
  14. //样式加载到后台
  15. add_action('admin_enqueue_scripts','vuespa_load_vues');

通过上述代码中的 if 判断,就只会在符合要求的 $hook 菜单上加载资源了。

总结

本节关注菜单权限方面,进行了菜单展示权限和菜单中加载资源的研究,这是我们日常开发中常用的功能。

通过上述两个权限的适当配合,可以一定程度上解决部分安全问题和页面加载缓慢的问题。

关于 WordPress 菜单的主要内容,到此为止,后续会根据实际问题,不定期更新相关内容。

赞(0)
未经允许不得转载:大象juǎn » 02:讲透WordPress 菜单开发 - 权限控制与加载指定JS