有些刚接触FleaPHP的童靴对于用户权限管理有些摸不着头脑,不得其门而入。其实,这个也不是什么难事,大家跟着我一步一步去做就行了。做完之后,如果还是不得要领,就不是你们的问题,而是我的水平有问题了。总之,有问题大家多扔几块砖头就是了,我这个人经常锻炼,身体比较抗糙。
闲话休赘,转入正题。
第一步:数据表准备
第一步自然是先创建好相关数据表。一般情况下,我们用到的数据表主要有:roles (角色表)、users (用户表)、users_roles (用户角色中间表)。
1、创建roles表,其表结构及数据如下图所示:
2、创建users表,其表结构如下图所示:
其中的uquota 、logontime 、enable 等字段在你的项目中未必用到,但其中的uid 、username 、password 字段则必须要有。
还有,必须注意其中的password 字段的长度,设为64 位,是由于我使用了PWD_CRYPT 方式加密密码(这也是默认的加密方式),如果使用PWD_MD5 加密方式,设为32 位就行了。
当然还有PWD_CLEARTEXT 、PWD_SHA1 、PWD_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;
这两句代码前面的双斜线,直接点击增加按钮提交数据,得到的数据如下所示:
(
[username] =>
[uid] =>
[name] =>
[gid] => 1
[roles] => Array
(
[0] => 4
)
[uquota] => 314572800
[enable] => 0
[save] => 增 加
[password] => 123456
)
(
[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