织梦重写用户权限频道ReWriteAdminChannel()
函数所在位置:include/userlogin.class.php,绝325行开始。
函数源代码:
function ReWriteAdminChannel() { //$this->userChannel $cacheFile = DEDEDATA.'/cache/admincat_'.$this->userID.'.inc'; //管理员管理的频道列表 $typeid = trim($this->userChannel); if( empty($typeid) || $this->getUserType() >= 10 ) { $firstConfig = "\$cfg_admin_channel = 'all';\r\n\$admin_catalogs = array();\r\n"; } else { $firstConfig = "\$cfg_admin_channel = 'array';\r\n"; } $fp = fopen($cacheFile, 'w'); fwrite($fp, '<'.'?php'."\r\n"); fwrite($fp, $firstConfig); if( !empty($typeid) ) { $typeids = explode(',', $typeid); $typeid = ''; foreach($typeids as $tid) { $typeid .= ( $typeid=='' ? GetSonIdsUL($tid) : ','.GetSonIdsUL($tid) ); } $typeids = explode(',', $typeid); $typeidsnew = array_unique($typeids); $typeid = join(',', $typeidsnew); fwrite($fp, "\$admin_catalogs = array($typeid);\r\n"); } fwrite($fp, '?'.'>'); fclose($fp); }
这个函数在织梦系统里面,只有一个地方使用就是在/dede/config.php里面,更新缓存栏目函数UpDateCatCache()中用过一次,在织梦其它地方,就再也没有用过,虽然,这个函数用的比较少,但是,也是非常重要的函数,当我们删除后台栏目时,就要更新一下缓存,这时就要用到这个更新缓存栏目了,也就是调用了重写用户权限频道函数了。
当我们在后台增加管理员时,如果一个栏目删除了,是不是原来的登录后台的这个后台管理员的对应的权限就要重写?因为,有可能删除的这个栏目正好是,这个管理员管理的权限,如果不更新缓存那么,这个后台登录管理员是不是仍然有操作这个栏目的权力,而实际上这个栏目已经删除了,这样可能会出错。
这样理解起来可能不好理解,还是先把这个函数分析完,再来理解吧。
源码分析:
第一行:定义了一个缓存文件$cachefile,位置在/data/cache/文件夹里面,在这行代码中$this->userID指的是用户登录后台的id,也就是数据库表# __admin对应的id,如下图所示。
这样我们就知道了,$cachefile文件名类似于admincat_1.inc,admincat_9.inc等。
第二行:把登录后台的管事员所管理的频道id赋给$typeid。当我们在后台增加管理员时,会设置这个管理员的管理的栏目,例如“频道管理员2”管理的栏目是“网页基础”和“站长图集”,即如下图所示。
也就是$typeid=1,6,这个我们也可以从数据库表#@__admin里面得知,如下图所示。
第三行:我把整个if条件语句作为一行,便于分析。从这一行开始,就开始拼合文件admincat_1.inc,文件内容类似如下:
<?php $cfg_admin_channel = 'all'; $admin_catalogs = array(); ?> 或 <?php $admin_catalogs = array; ?>
其中,$admin_catalogs还有可能等于array(1,6),不管理如何,从第三行开始就开始拼合文件admincat_1.inc,这也是以this->userid为1,也就是越级管理员为例子,如果是“频道操作员”的话,那么,文件就是admincat_9.inc了。
首先判断$typeid为空或表# __admin中usertype字段值大于或等于10(等于10相当一超级管理员)则,把字符串赋也就是文件内容,赋给$firstConfig变量。否则,$firstConfig=$cfg_admin_channel='array',跟上面的内容有点类似,但是,$cfg_admin_channel的值完全不一样。
第四行:打开文件fopen($cacheFile,'w'),请注意:这里打开文件以重写的方式打开,这个打开方式很重要,一般情况下我们都是以追加方式a打开文件,而此处,用的是以重写也就是覆盖方式打开,也只有这样,才能把我们删除的栏目(如果后台登录人员有管理这个栏目的权限的话)权限覆盖掉。
第五行:把<?php写入文件$cachefile。
第六行:写入具体内容$firstconfig。
第七行:也是为了分析方便,把整个if作为一行,其实,准确讲应当叫一块。
首先,判断$typeid是否为空,若不为空,例如本例子中的“频道管理2”$typeid=1,6,也就是管理顶级id为1和6的栏目。
若不为空,则把$typeid通过explode()函数转换成数组array(1,6)赋给$typeids。
定义变量$typeid=''。
其次,遍历这个$typeids数组,遍历这个数组的目的就是把遍历出来的id值赋给$admin_catalogs。通过GetSonIdsUL()函数,把id为1和6的栏目id遍历出来存储到期$typeid里面,这里要注意的是:在这个三元操作里面的$typeid指的是条件判断中的$typeid,而不是上面定义的变量$typeid='',这个如果分不清会弄乱,个人觉得这样定义不好,容易使我们弄混乱,如果把这个变量起个其它名称会更容易理解的。
经过遍历后,$typeid存储的值类似3,4,5是以逗号分隔的id为1和6的子栏目id的值。
最后,再通过explode()函数,把这个id值组装成数组,并赋给$typeids,然后,再通过函数array_unique()移除数组中重复的值。然后,再通过函数join()通过豆号把数组拼接成字符中。然后,把这些字符放在$admin_catalogs=array($typeid)里面,写入文件$cachefile里面
第八行:写入结束符号:?>
第九行:关闭文件。
现在我就以会员kf,也就是信息发布员登录后台,kf在数据库表对应的信息如下所示。
kf的id为8,如果按上面的分析,kf对应的缓存文件应当是admincat_8.inc。
kf的typeid管理的栏目id为1,6,通过上面的分析,kf里面的$admin_catalogs的值应当为array(1,2,3,4,5,6)。
为了测试我用kf登录后台,然后,在data/cache文件夹下面果然找到了admincat_8.inc,如下图所示。
打开admincat_8.inc这个文件,如下图所示。
kf的管理栏目$admin_catalogs对应的id果然是array(1,2,3,4,5,6)。
通过上面的分析我们知道,只要是你登录后,就会在data/cache文件夹下面生成你在表# __admin里面对应的id的文件,我们看一下表# __admin,发现这个表的id有1,8,9,所以,我们在这个文件夹下面能看到admincat_1.inc、admincat_8.inc、admincat_9.inc。
其中,admincat_9.inc和admincat_1.inc里面的内容是一样的,为什么?请看数据库表# __admin如下图所示。
这二个id为9对应的typeid为空,id为9的对应的usertype值为10,所以,生成的内容都为:
<?php $cfg_admin_channel = 'all'; $admin_catalogs = array(); ?>
这个我们已经在上面分析了。
可能大家还有可能问一个问题,为什么我们登录后台就会生成类似上面的三个文件?因为,当我们登录后台,填写好用户名后,程序就会调用$cuserLogin->keepUser()方法,这个方法自然,就调用这个重写用户权限频道函数数了(这时正确叫法是方法),所以,就生成了上面的三个文件及其内容。