FleaPHP的用户权限管理

有些刚接触FleaPHP的童靴对于用户权限管理有些摸不着头脑,不得其门而入。其实,这个也不是什么难事,大家跟着我一步一步去做就行了。做完之后,如果还是不得要领,就不是你们的问题,而是我的水平有问题了。总之,有问题大家多扔几块砖头就是了,我这个人经常锻炼,身体比较抗糙。

闲话休赘,转入正题。

第一步:数据表准备

第一步自然是先创建好相关数据表。一般情况下,我们用到的数据表主要有:roles (角色表)、users (用户表)、users_roles (用户角色中间表)。

1、创建roles表,其表结构及数据如下图所示:


 
2、创建users表,其表结构如下图所示:


 
其中的uquotalogontimeenable 等字段在你的项目中未必用到,但其中的uidusernamepassword 字段则必须要有。
还有,必须注意其中的password 字段的长度,设为64 位,是由于我使用了PWD_CRYPT 方式加密密码(这也是默认的加密方式),如果使用PWD_MD5 加密方式,设为32 位就行了。
当然还有PWD_CLEARTEXTPWD_SHA1PWD_SHA2 等其它的加密方式,但由于平时少用,就不要理它了。

如果需要设置为其它非默认的加密方式,可以在保存用户数据前显式指明,如下所示:

$table->$encodeMethod = PWD_MD5;
 

3、创建users_roles中间表,其表结构如下图所示:


 
这样,创建好相关数据表后,就可以进行第二步了。

第二步:编写数据表对象代码

1、编写roles数据表对象代码,如下所示:

<?php

FLEA::loadClass('FLEA_Rbac_RolesManager');

/**
 * 角色数据表对象
 */
class Table_Roles extends FLEA_Rbac_RolesManager
{
    var $tableName = 'roles';
    var $primaryKey = 'role_id';
}
?>
 

注意:角色数据表对象Table_Roles 是继承父类FLEA_Rbac_RolesManager 的。

2、编写users数据表对象代码,如下面所示:

<?php

FLEA::loadClass('FLEA_Rbac_UsersManager');

/**
 * 用户数据表对象
 */
class Table_Users extends FLEA_Rbac_UsersManager
{
    var $tableName = 'users';
    var $primaryKey = 'uid';

    /**
     * 定义多对多关联
     *
     * @var array
     */
    var $manyToMany = array(
        'tableClass' => 'Table_Roles',
        'mappingName' => 'roles',
        'joinTable' => 'users_roles',
        'fields' => 'role_id, rolename, rolename_cn', // 只读取role_id, rolename, rolename_cn字段数据
        'enable' => false,
    );
}
?>
 

注意:用户数据表对象Table_Users 是继承父类FLEA_Rbac_UsersManager 的。
另,用户数据表users 与角色数据表roles 定义为多对多的关系,这个应该没有疑问吧?难道不是吗?

下面进行第三步,数据模型对象代码的编写。

第三步:编写数据模型对象代码

众所周知,FleaPHP是一个MVC框架,业务逻辑代码在数据模型对象中实现,这是一个标准,也是一个建议。当然业务逻辑代码也可在其它地方实现,但在此不推荐。

1、编写角色数据模型对象代码,如下所示:

<?php

/**
 * 角色模型对象
 */
class Model_Roles
{
    var $_tbRoles;
   
    /**
     * 构造器
     *
     */
    function Model_Roles()
    {
        $this->_tbRoles = & FLEA::getSingleton('Table_Roles');
    }

    /**
     * 构造角色多选框
     *
     * 指派用户多个角色时使用
     * @param int $selected  选定项
     * @return string 返回html代码
     */
    function makeRoleCheckboxgroups($selected = null)
    {
        $ui = & FLEA::initWebControls();
        //FLEA::loadFile('FLEA_Helper_Array.php');

        $sort = '`role_id` ASC';
        $rows = $this->_tbRoles->findAll(null, $sort);
        //dump($rows);
        //exit;

        $items = array_to_hashmap($rows, 'rolename_cn', 'role_id');
        return $ui->control(
            'checkboxgroup',              // 控件类型,指示构造多选框
            'roles',                      // 多选框名称及ID
            array(
                'items' => $items,          // 多选框数据项
                'selected' => $selected,  // 已选项
                'multirow' => false,      // 是否显示多行
                'cols' => 3,              // 每行显示3列
                'table' => false,          // 是否输出表格
                //'class' => "radio",      // 自定义样式
            ),
            true
        );
    }

    /**
     * 构造角色单选框
     *
     * 指派用户单一角色时使用
     * @param int $selected  选定项
     * @return string 返回html代码
     */
    function makeRoleRadiogroups($selected = null)
    {
        $ui = & FLEA::initWebControls();
        //FLEA::loadFile('FLEA_Helper_Array.php');

        $sort = '`role_id` ASC';
        $rows = $this->_tbRoles->findAll(null, $sort);
        //dump($rows);
        //exit;

        $items = array_to_hashmap($rows, 'rolename_cn', 'role_id');
        return $ui->control(
            'radiogroup',                    // 控件类型,指示构造单选框
            'roles[]',                        // 单选框名称及ID
            array(
                'items' => $items,            // 单选框数据项
                'selected' => $selected,    // 已选项
                'multirow' => false,        // 是否显示多行
                'cols' => 3,                // 每行显示3列
                'table' => false,            // 是否输出表格
                //'class' => "radio",        // 自定义样式
            ),
            true
        );
    }
}
 

注意上面代码中构造多选框的makeRoleCheckboxgroups() 方法和构造单选框的makeRoleRadiogroups() 方法的名称 roles ,这是用户数据表对象中users_roles 中间表的映射名。还要注意两者的区别,一个为 roles ,一个 roles[] 。这样做是有理由的,其理由将在后面说明。

2、编写用户数据模型对象代码,如下所示:

<?php

/**
 * 用户模型对象
 */
class Model_Users
{
    var $_tblUsers;

    /**
     * 构造函数
     *
     */
    function Model_Users()
    {
        $this->_tblUsers = & FLEA::getSingleton('Table_Users');
    }

    /**
     * 保存数据
     *
     * @param array $row
     * @param Boolean $enableLink
     * @return int
     */
    function save(& $row, $enableLink = true)
    {
        if ($enableLink) {
            $this->_tblUsers->enableLink('roles');
        }
        return $this->_tblUsers->save($row);
    }

    /**
     * 读取单条数据记录
     *
     * @param string $conditions
     * @return array
     */
    function find($conditions)
    {
        return $this->_tblUsers->find($conditions);
    }

    /**
     * 删除记录
     *
     * @param array $condtion
     */
    function remove($condtion)
    {
        $this->_tblUsers->enableLink('roles');
        $this->_tblUsers->removeByConditions($condtion);
    }

    /**
     * 更新密码
     *
     * @param string $username
     * @param string $newPassword
     * return Bools
     */
    function updatePassword($username, $newPassword)
    {
        return $this->_tblUsers->updatePassword($username, $newPassword);
    }
   
    /**
     * 处理用户列表数据
     *
     * @param unknown_type $rows
     * @return unknown
     */
    function getAdminUsersList(& $rows)
    {
          $i=0;
        foreach ($rows as $row) {
            $rows[$i]['xh'] = $i + 1;
            $rows[$i]['uquota'] = round($row['uquota']/(1024*1024), 2);
            $rows[$i]['status'] = ($row['enable'])?"<font color=\"#FF0000\">已激活</font>":"未激活";
            $rows[$i]['isOpen'] = ($row['enable']) ? 0 : 1;
            $recs = $row['roles'];
            $rls = array();
            foreach ($recs as $rec) {
                $rls[] = $rec['rolename_cn'];
            }
            $rows[$i]['rls'] = implode(', ', $rls);
            $i++;
        }
        return $rows;
    }

    /**
     * 构造用户状态单选框
     *
     * @param int $selected
     * @return 返回HTML代码
     */
    function makeEnableUserRadiogroups($selected = null)
    {
        $ui = & FLEA::initWebControls();
        $items = array(
            '激活' => 1,
            '不激活' => 0,
        );
        return $ui->control(
            'radiogroup',
            'enable',
            array(
                'items' => $items,
                'selected' => $selected,
                'multirow' => false,
                //'cols' => 3,
                'table' => true,
            ),
            true
        );
    }
}
?>
 

第四步:编写HTML模板代码

下面的代码为与分派角色相关的部分代码。

......

<tr>
  <th>分派角色:</th>
  <td>{{$user.html_roles}}</td>
</tr>

......
 

第五步:编写用户管理控制器类代码

由于用户管理控制器类代码太长,因此只节选部分相关代码:

<?php
/**
 * 办公网站后台管理——用户管理控制器类
 *
 * 文 件 名:Admin/Controller/Users.php
 * 作    者:hegz
 * 更新时间:2010/05/08
 *
 */

/**
 * 装入后台管理控制器基类
 */
//{{
FLEA::loadClass('Controller_AdminBase');
//}}

class Controller_Users extends Controller_AdminBase
{   
    /**
     * 构造函数
     *
     * @return Controller_Default
     */
    function Controller_Users()
    {
        parent::Controller_AdminBase();
        $this->_modelUsers = & FLEA::getSingleton('Model_Users');
        $this->_modelRoles = & FLEA::getSingleton('Model_Roles');
    }
   
    /**
     * 缺省操作
     *
     */
    function actionIndex()
    {
        ......
    }
  
   /**
    * 显示增加用户界面操作
    *
    */
   function actionAdd()
   {
           $data = array();
       
        ......
        // 单角色
        $data['html_roles'] = $this->_modelRoles->makeRoleRadiogroups(4);
        // 多角色
        //$data['html_roles'] = $this->_modelRoles->makeRoleCheckboxgroups(4);
       
        ......
       
        $this->tpl->assign('user', $data);
        $this->display('user_add_edit.tpl');
   }
  
   /**
    * 保存数据
    *
    */
   function actionSave()
   {
           $data = $_POST;
           $data['password'] = '123456';
          
        ......

        //$data['roles'][0] = $data['role_id']; // 准备角色数据
            
        //dump($data);    // 显示提交到后台的数据
           //exit;
          
           $this->_modelUsers->save($data);
           redirect($this->_url());
   }

   /**
    * 显示用户编辑界面操作
    *
    */
   function actionEdit()
   {
   		$conditions = array(
   			array('uid', (int)$_GET['id'], '='),
   		);
   		$data = $this->_modelUsers->find($conditions);
   		
   		......
		
		/**
		 * 多角色
		 */
		/*$roles = $data['roles'];
    	$roleIds = array();
    	foreach ($roles as $role) {
    		$roleIds[] = $role['role_id'];
    	}
		$data['html_roles'] = $this->_modelRoles->makeRoleCheckboxgroups($roleIds);*/
		// 单一角色
		$data['html_roles'] = $this->_modelRoles->makeRoleRadiogroups($data['roles'][0]['role_id']);
		
		......
   		
   		$this->tpl->assign('user', $data);
   		$this->display('user_add_edit.tpl');
   }
  
   ......
}
?>
 


用户管理控制器类构造完毕后,就可以运行程序进行测试了。

程序生成的界面效果图如下:


 
把用户控制器类的代码修改为:

   /**
    * 显示增加用户界面操作
    *
    */
   function actionAdd()
   {
       
        ......
        // 单角色
        //$data['html_roles'] = $this->_modelRoles->makeRoleRadiogroups(4);
        // 多角色
        $data['html_roles'] = $this->_modelRoles->makeRoleCheckboxgroups(4);
       
        ......
       
   }
 

在增加用户时将可分派多角色,如下图所示:


 
数据测试

增加如图所示用户:



提交后,将得到如下数据:


 
查看提交数据

去掉用户管理控制器类actionSave 方法中:

//dump($data);
//exit;
 

这两句代码前面的双斜线,直接点击增加按钮提交数据,得到的数据如下所示:

单角色:
Array
(
[username] =>
[uid] =>
[name] =>
[gid] => 1
[roles] => Array
(
[0] => 4
)

[uquota] => 314572800
[enable] => 0
[save] => 增 加
[password] => 123456
)

 

多角色:
Array
(
[username] =>
[uid] =>
[name] =>
[gid] => 1
[roles] => Array
(
[0] => 2
[1] => 4
)

[uquota] => 314572800
[enable] => 0
[save] => 增 加
[password] => 123456
)
 

注意上面的roles 数据,这是一个二维数组。不知童靴们是否记得,前面我曾说过,roles 为用户数据表对象中users_roles 中间表的映射名称。只有将这样格式的二维角色数组数据传入save() 方法,才能正确处理角色关联数据。这就是在角色模型对象中,将多选框及单选框控件的控件名设置为roles的原因。

如果多选框及单选框控件的控件名不是设置为roles ,比如设置为role_id ,为了保证能够正确处理角色关联数据,则在将数据传入save() 中时,必须先进行处理。如下所示:

$data['roles'][0] = $data['role_id']; // 准备角色数据
 


结束语

用户权限的管理先介绍到这里吧。水平所限,错漏实所难免。总而言之,有错误的地方,欢迎指正,有不明白的地方,请提出来。或者日后有需要补充的地方,我将及时进行补充。

 

 

论坛贴:http://qeephp.com/bbs/viewthread.php?tid=10972&page=1&extra=#pid56703

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值