热搜词
发表于 2022-9-18 08:00:36 | 显示全部楼层 |阅读模式
Veno-File-Manager (VFM4)云盘,增加用户只读游客无权限公共目录的方法
解决方法:
1.新增一个用户只读公共目录(user_read_dirs)数组配置
打开 根目录/vfm-admin/config-master.php 文件,新添一个 'user_read_dirs'数组配置参数,代码如下:
  1.   'user_read_dirs' =>
  2.   array (
  3.     0 => 'user_public',
  4.     1 => 'user_temp',
  5.   ),
复制代码

2.为用户只读公共目录(user_read_dirs)设置相应类中成员方法

打开 根目录/vfm-admin/class/class.location.php 文件,参考类中成员方法(用户私有可读写目录) checkUserDir 和 editAllowed() 代码,

新添用户只读公共目录 userPublicDir()  和userReadtAllowed() 成员方法,代码如下:
  1.         /**
  2.          * 检查用户是否允许读取当前目录,
  3.          * based on configuration settings
  4.          *
  5.          * @param string $relative relative path to index.php
  6.          *
  7.          * @return true/false
  8.          */
  9.         public function userReadtAllowed($relative = false)
  10.         {
  11.             global $setUp;
  12.             $totdirs = count($this->path);

  13.             $father = $this->getDir(false, true, false, $totdirs -1);
  14.             $hidden_dirs = $setUp->getConfig('hidden_dirs');
  15.             if (!$hidden_dirs) {
  16.                 return false;
  17.             }
  18.             if (in_array(basename($father), $hidden_dirs)) {
  19.                 return false;
  20.             }
  21.                 if ($this->userPublicDir($relative) === true) {
  22.                     return true;
  23.                 }                        
  24.            return false;
  25.         }


  26.        /**
  27.          * 检查目录是否可供用户只读使用
  28.          *
  29.          * @param string $relative relative path to index.php
  30.          *
  31.          * @return true/false
  32.          */
  33.         public function userPublicDir($relative = false)
  34.         {
  35.             global $gateKeeper;
  36.             global $setUp;

  37.             $thispath = $this->getDir(true, false, false, 0, $relative);
  38.             if (!is_dir(realpath($thispath))) {
  39.                 return false;
  40.             }
  41.                         
  42.             $startdir = $setUp->getConfig('starting_dir');
  43.             $publicdirsarray = $setUp->getConfig('user_read_dirs') !== null ? $setUp->getConfig('user_read_dirs') : array();
  44.             $thiscleanpath = ltrim($thispath, './');
  45.             $cleanstartdir = rtrim(ltrim($startdir, './'), '/');
  46.             $thispatharray = explode('/', $thiscleanpath);
  47.             $checkpath = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? $thispatharray[1] : $thispatharray[0];
  48.             $pathcounter = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? (int)2 : (int)1;        
  49.                                                 
  50.                         //检查分配的多个公共目录'user_read_dirs'文件夹
  51.             foreach ($publicdirsarray as $value) {

  52.                 //检查是否分配了子/子文件夹
  53.                 $userdirarray = explode('/', $value);
  54.                 $usersubs = count($userdirarray) - 1;
  55.                 if ($usersubs > 0) {
  56.                     $subscounter = $usersubs + $pathcounter;
  57.                     for ($i = $pathcounter; $i < $subscounter; $i++) {
  58.                         $checkpath .= '/'.$thispatharray[$i];
  59.                     }
  60.                 }

  61.                 //最后,检查用户是否可以访问该位置
  62.                 if ($value === $checkpath) {
  63.                     return true;
  64.                 }
  65.                         }

  66.             return false;
  67.         }  
复制代码

新添游客只读公共目录 guestPublicDir和guestReadtAllowed() 成员方法,代码如下:
  1.         /**
  2.          * 检查游客是否允许读取当前目录,
  3.          * based on configuration settings
  4.          *
  5.          * @param string $relative relative path to index.php
  6.          *
  7.          * @return true/false
  8.          */
  9.         public function guestReadtAllowed($relative = false)
  10.         {
  11.             global $setUp;
  12.             $totdirs = count($this->path);

  13.             $father = $this->getDir(false, true, false, $totdirs -1);
  14.             $hidden_dirs = $setUp->getConfig('hidden_dirs');
  15.             if (!$hidden_dirs) {
  16.                 return false;
  17.             }
  18.             if (in_array(basename($father), $hidden_dirs)) {
  19.                 return false;
  20.             }
  21.                 if ($this->guestPublicDir($relative) === true) {
  22.                     return true;
  23.                 }                        
  24.            return false;
  25.         }


  26.        /**
  27.          * 检查目录是否可供游客使用
  28.          *
  29.          * @param string $relative relative path to index.php
  30.          *
  31.          * @return true/false
  32.          */
  33.         public function guestPublicDir($relative = false)
  34.         {
  35.             global $gateKeeper;
  36.             global $setUp;

  37.             $thispath = $this->getDir(true, false, false, 0, $relative);
  38.             if (!is_dir(realpath($thispath))) {
  39.                 return false;
  40.             }
  41.                         
  42.             $startdir = $setUp->getConfig('starting_dir');
  43.             $publicdirsarray = $setUp->getConfig('public_dirs') !== null ? $setUp->getConfig('public_dirs') : array();
  44.             $thiscleanpath = ltrim($thispath, './');
  45.             $cleanstartdir = rtrim(ltrim($startdir, './'), '/');
  46.             $thispatharray = explode('/', $thiscleanpath);
  47.             $checkpath = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? $thispatharray[1] : $thispatharray[0];
  48.             $pathcounter = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? (int)2 : (int)1;        
  49.                                                 
  50.                         //检查分配的多个公共目录'public_dirs'文件夹
  51.             foreach ($publicdirsarray as $value) {

  52.                 //检查是否分配了子/子文件夹
  53.                 $userdirarray = explode('/', $value);
  54.                 $usersubs = count($userdirarray) - 1;
  55.                 if ($usersubs > 0) {
  56.                     $subscounter = $usersubs + $pathcounter;
  57.                     for ($i = $pathcounter; $i < $subscounter; $i++) {
  58.                         $checkpath .= '/'.$thispatharray[$i];
  59.                     }
  60.                 }

  61.                 //最后,检查用户是否可以访问该位置
  62.                 if ($value === $checkpath) {
  63.                     return true;
  64.                 }
  65.                         }
  66.                                 
  67.             return false;
  68.         }
复制代码

3.修改文件夹类,把用户只读目录(user_read_dirs)添加进用户目录
打开  根目录/vfm-admin/class/class.dirs.php   文件,查找数组变量 $userpatharray ,代码如下:
  1. $userpatharray = $gateKeeper->getUserInfo('dir') !== null ? json_decode($gateKeeper->getUserInfo('dir'), true) : false;
复制代码

把公共目录(public_dir)和用户只读目录(user_read_dirs)添加到 $userpatharray数组中,修改后代码为:
  1. $userpatharray = $gateKeeper->getUserInfo('dir') !== null ? json_decode($gateKeeper->getUserInfo('dir'), true) : false;
  2. $public_dirs = $setUp->getConfig('public_dirs');
  3. $user_read_dirs = $setUp->getConfig('user_read_dirs');
  4. @$userpatharray = array_merge($userpatharray,$public_dirs);
  5. if($gateKeeper->isUserLoggedIn() ){
  6. @$userpatharray = array_merge($userpatharray,$public_dirs,$user_read_dirs);
  7. }
复制代码

再查找仅获取用户分配的文件夹(如果有)遍历语句,添加  !$this->location->guestReadtAllowed($relative) 和   !$this->location->userReadtAllowed($relative) 两个条件,修改后如下:
  1. if (is_array($content)) {
  2.     foreach ($content as $item) {

  3.         if (is_dir($item)) {

  4.             $mbitem = Utils::mbPathinfo($item);
  5.             $item_basename = $mbitem['basename'];

  6.             // get only users' assigned folders if any
  7.             if ($userpatharray
  8.             && !in_array($item_basename, $userpatharray)
  9.             && !$this->location->editAllowed($relative)
  10.             && !$this->location->guestReadtAllowed($relative)
  11.             && !$this->location->userReadtAllowed($relative)) {
  12. continue;
  13.             }
  14.         
  15.             // Skip /vfm-admin/ if the main uploads dir is the root
  16.             if (!$hidefiles || ($hidefiles && !in_array($item_basename, $hidden_dirs))) {
  17. $this->dirs[] = new Dir($item_basename, $this->location, $relative);
  18.             }
  19.         }
  20.     }
  21. }
复制代码

4.修改前端显示UI代码,让游客和登录用户显示公共目录(public_dirs)、用户只读目录(user_read_dirs)和根目录(starting_dir)中的文件
打开根目录 vfm-admin/template/list-files.php 文件,把条件判断语句改为如下格式:
  1. if ($gateKeeper->isAccessAllowed()){
  2. if( $location->editAllowed()
  3.     || $location->guestReadtAllowed()
  4.     || $location->userReadtAllowed() && $gateKeeper->isUserLoggedIn()
  5.     || $location->getCleanPath() ==="") {
  6.     if ($gateKeeper->isAllowed('view_enable')) {

  7.   列表显示文件代码 }
  8.   显示上传文件功能区块代码 }
  9. }
复制代码
存在问题,当以上代码中添加 guestReadtAllowed()、userReadtAllowed() 、getCleanPath() ==="" 三条判断语句后,会出现一个新的bug,即编辑(editor)用户打开首页、游客公共目录(public_dirs)或用户只读公共目录(user_read_dirs),一直显示加载状态,打不开网页。
编辑用户打开首页不正常.jpg

解决方法:
打开根目录 vfm-admin/include/load-js.php文件,查找与更名 (rename_enable) 相关代码,把显示条件判断语句改为如下格式:
单选操作(右侧):更名

  1. if ($gateKeeper->isAllowed('rename_enable') && $location->editAllowed())
复制代码


解决浏览公共目录(user_read_dirs)下文件时时,“多选操作”菜单中仍显示移动、复制和删除按钮的问题:

多选操作.png

大概在65行左右,添加条件判断语句,使“多选操作”菜单中不显示移动、复制和删除按钮,改后代码如下:
  1. if ($gateKeeper->isAllowed('move_enable') && $location->checkUserDir()) { ?>
  2.     <li>
  3.         <a class="multimove dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#archive-map-move" data-action="move">
  4.             <i class="bi bi-arrow-right"></i>
  5.             <?php echo $setUp->getString("move"); ?>
  6.         </a>
  7.     </li>
  8.     <?php
  9. }
  10. if ($gateKeeper->isAllowed('copy_enable') && $location->checkUserDir()) { ?>
  11.    <li>
  12.         <a class="multicopy dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#archive-map-copy" data-action="copy">
  13.             <i class="bi bi-clipboard-check"></i>
  14.             <?php echo $setUp->getString("copy"); ?>
  15.         </a>
  16.     </li>
  17.     <?php
  18. }
  19. if ($gateKeeper->isAllowed('delete_enable') && $location->checkUserDir()) { ?>
  20.     <li><a class="multic dropdown-item" href="#">
  21.             <i class="bi bi-trash"></i>
  22.             <?php echo $setUp->getString("delete"); ?>
  23.         </a>
  24.     </li>
  25.     <?php
  26. } ?>
复制代码


也可以把条件语句改为如下代码:
  1. if ($gateKeeper->isAllowed('move_enable') && !$location->guestReadtAllowed() && !$location->userReadtAllowed() && $location->getCleanPath() !=="")
复制代码

解决PC列表模式下显示公共目录(user_read_dirs)下文件时时,表格仍显示重命名和删除列的问题:

不显示表格中编辑和删除列.png

大概在137行左右,添加条件判断语句,使表格不显示重命名和删除列,改后代码如下:

  1. if ($gateKeeper->isAllowed('rename_enable') && $location->checkUserDir()) { ?>
  2.     <td class="small text-center gridview-hidden d-none d-md-table-cell">
  3.         <i class="bi bi-pencil"></i>
  4.     </td>
  5.     <?php
  6. } ?>
  7. <td class="small text-center gridview-hidden">
  8. <?php
  9. if ($gateKeeper->isAllowed('delete_enable') && $location->checkUserDir()) {  ?>
  10.     <i class="bi bi-trash d-none d-md-block"></i>
  11.     <?php
  12. } ?>
复制代码

5.修改ajax请求代码,使游客和登录用户能获取到公共目录(public_dirs)、用户只读目录(user_read_dirs)和根目录(starting_dir)中的文件
打开根目录  /vfm-admin/ajax/get-files.php  文件,查找如下代码:
  1. if ($gateKeeper->isAccessAllowed() && $location->editAllowed('../../') && $gateKeeper->isAllowed('view_enable'))
  2. {
  3. $fullpath = $location->getFullPath();
  4. ...
  5. }
复制代码

改为如下代码:

  1. $cleanlocdir = rtrim(ltrim($locdir, './'), '/');
  2. $startdir = './'.$setUp->getConfig('starting_dir');
  3. $cleanstartdir = rtrim(ltrim($startdir, './'), '/');

  4. if ($cleanlocdir === $cleanstartdir
  5. || $gateKeeper->isAccessAllowed()
  6. && $location->guestReadtAllowed('../../')  
  7. || $location->editAllowed('../../')  
  8. || $location->userReadtAllowed('../../')
  9. && $gateKeeper->isAllowed('view_enable')) {
  10.     $fullpath = $location->getFullPath();
  11. ...
  12. }
复制代码

解决平铺视图模式下显示公共目录(user_read_dirs)下文件时时,在文件右上角显示重命名和删除按钮问题:

平铺模式-去掉删除按钮.png

大概在271行左右,添加条件判断语句,使平铺视图文件右上角不显示重命名和删除按钮,改后代码如下:
  1. if ($gateKeeper->isAllowed('rename_enable') && $location->editAllowed('../../')) {
  2.     $data['icon'] .= '<div class="icon text-center minibtn">
  3.         <button class="round-btn rename" data-thisdir="'.$thisdir.'" data-thisext="'.$ext.'" data-thisname="'.$normalizedName.'">
  4.             <i class="bi bi-pencil-square"></i>
  5.         </button>
  6.     </div>';
  7. }
  8. if ($gateKeeper->isAllowed('delete_enable') && $location->editAllowed('../../')) {
  9.     $data['icon'] .= '<div class="minibtn">
  10.         <button class="round-btn del" data-name="'.$thisfile.'" data-link="'.$thisdel.'&h='.$cash.'">
  11.             <i class="bi bi-trash"></i>
  12.         </button>
  13.     </div>';
  14. }
复制代码


解决PC浏览器打开公共目录(user_read_dirs)时,在文件列表右侧显示重命名和删除按钮问题:
pc-去掉删除按钮.png

大概在326行左右,添加条件判断语句,使文件列表右侧不显示重命名和删除按钮,改后代码如下:
  1. $data['delete'] = '';

  2. if ($gateKeeper->isAllowed('delete_enable') && $location->editAllowed('../../')) {
  3.     $data['delete'] .= '<div class="d-none d-md-block"><button class="round-btn btn-mini del" data-name="'.$thisfile.'" data-link="'.$thisdel.'&h='.$cash.'"><i class="bi bi-x-lg"></i></button></div>';
  4. }
复制代码

解决手机端打开公共目录(user_read_dirs)时,在文件列表右侧显示重命名和删除按钮问题:

手机版-去掉删除按钮.png

大概在342行左右,添加条件判断语句,使文件列表右侧不显示重命名和删除按钮,改后代码如下码:
  1. if ($gateKeeper->isAllowed('rename_enable') && $location->editAllowed('../../')) {
  2.     $data['delete'] .= '<li>
  3.     <a class="rename dropdown-item" data-thisdir="'.$thisdir.'" data-thisext="'.$ext.'" data-thisname="'.$normalizedName.'" href="javascript:void(0)">
  4.     <i class="bi bi-pencil-square"></i> '.$setUp->getString("rename").'</a></li>';
  5. }
  6. if ($gateKeeper->isAllowed('delete_enable') && $location->editAllowed('../../')) {
  7.     $data['delete'] .= '<li>
  8.     <a class="del dropdown-item" href="javascript:void(0)" data-link="'.$thisdel.'&h='.$cash.'" data-name="'.$thisfile.'"><i class="bi bi-trash"></i> '.$setUp->getString("delete").'</a></li>';
  9. }
复制代码


6.修改ajax请求代码,使游客无权获取用户只读公共目录(user_read_dirs)内子目录。

打开根目录  /vfm-admin/ajax/get-dirs.php  文件,查找如下代码:
  1. if ($gateKeeper->isAccessAllowed() && $gateKeeper->isAllowed('viewdirs_enable')) {
  2.     $fullpath = $location->getFullPath();
  3.     ...
  4. } // end allowed
复制代码

再此基础上再添加多条判断语句,修改后代码如下:
  1. $cleanlocdir = rtrim(ltrim($locdir, './'), '/');
  2. $startdir = './'.$setUp->getConfig('starting_dir');
  3. $cleanstartdir = rtrim(ltrim($startdir, './'), '/');

  4. if ($cleanlocdir === $cleanstartdir
  5.     && $gateKeeper->isAccessAllowed()
  6.     && $gateKeeper->isAllowed('viewdirs_enable')
  7.     || $location->guestReadtAllowed('../../')  
  8.     || $location->editAllowed('../../')  
  9.     || $location->userReadtAllowed('../../')  
  10.     && $gateKeeper->isUserLoggedIn()) {
  11.     $fullpath = $location->getFullPath();
  12.     ...
  13. } // end allowed
复制代码

实现此功能相关文件:
根目录/vfm-admin/config-master.php                   //配置用户只读目录(user_read_dirs)
根目录/vfm-admin/class/class.location.php           //检查当前目录的用户权限
根目录/vfm-admin/class/class.dirs.php                //遍历所有用户私有文件夹下的子目录,使可以列表显示
根目录/vfm-admin/template/list-files.php            //列表显示文件UI模板
根目录/vfm-admin/template/list-folders.php     //列表显示文件夹模板
根目录 /vfm-admin/ajax/get-files.php                //获取并显示文件名称
根目录 /vfm-admin/ajax/get-dirs.php               //获取并显示文件夹名称
根目录vfm-admin/include/load-js.php             //单选操作(右侧):更名

全部评论3
灰儿 发表于 2022-9-19 00:06:03 | 显示全部楼层
http://www.admin365.cn/thread-46373-1-1.html  
Veno-File-Manager (VFM4)云盘,添加仅限游客和用户访问公共目录

http://www.admin365.cn/thread-46386-1-1.html  
Veno-File-Manager (VFM4)云盘让登录用户可显示公共文件夹方法

http://www.admin365.cn/thread-46442-1-1.html
Veno-File-Manager (VFM4)云盘,增加用户只读游客无权限公共目录
回复

使用道具 举报

回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|管理员之家 ( 苏ICP备2023053177号-2 )

GMT+8, 2024-12-27 19:39 , Processed in 0.179576 second(s), 28 queries .

Powered by Discuz! X3.5

Cpoyright © 2001-2024 Discuz! Team