继续来记录GGZOO的开发过程
这次做的是一个简单的会员系统
插件名:TeMember
功能:用户在前台登录、注册、修改个人资料、查看自己发布的内容和评论;支持使用社交帐号登录(QQ、微博等)
新增字段:table.users.qqOpenId(QQ登录)、table.users.weiboOpenId(微博登录)
首先是添加前端需要的一些页面,直接使用Helper::addRoute
添加相关的路由就可以了
Helper::addRoute('member', '/member/','TeMember_Widget','index');
//其他路由省略
因为插件涉及到用户的一些数据操作,所以其中的TeMember_Widget
直接继承自Widget_Abstract_Users
class TeMember_Widget extends Widget_Abstract_Users{
//风格路径
private $_themeDir;
//插件配置
private $_pluginOptions;
//初始化方法:风格路径、插件配置等等
public function __construct($request, $response, $params = NULL){
parent::__construct($request, $response, $params);
$this->_themeDir = rtrim($this->options->themeFile($this->options->theme), '/') . '/';
$this->_pluginOptions = $this->options->plugin('TeMember');
/** 初始化皮肤函数 */
$functionsFile = $this->_themeDir . 'functions.php';
if (!$this->_invokeFromOutside && file_exists($functionsFile)) {
require_once $functionsFile;
if (function_exists('themeInit')) {
themeInit($this);
}
}
//省略……
}
//输出模板
public function render($themeFile){
/** 文件不存在 */
if (!file_exists($this->_themeDir . $themeFile)) {
Typecho_Common::error(500);
}
/** 输出模板 */
require_once $this->_themeDir . $themeFile;
}
/**
* 获取主题文件
*
* @access public
* @param string $fileName 主题文件
* @return void
*/
public function need($fileName){
require $this->_themeDir . $fileName;
}
/**
* 会员中心首页
*
* @access public
* @return void
*/
public function index(){
if (!$this->user->hasLogin()) {
/** 直接返回 */
$this->response->redirect($this->___loginUrl());
}
$this->current = 'index';
$this->render('member/index.php');
}
//相关业务代码
}
写好相应的模版,页面就可以显示了:
登录页面
用户中心页面
个人资料页面
这里就不一一的贴出来了,欢迎大家去测试
地址:http://www.ggzoo.com
暂时只支持使用QQ
进行登录,发现问题记得过来反馈下哦
好了,还是继续吧
保存个人资料没有使用后台的方法,而是直接在插件中进行的:
首先生成一个带token
的表单提交的地址
**
* 获取修改资料提交地址
*
* @access protected
* @return string
*/
protected function ___profileAction()
{
return $this->widget('Widget_Security')->getTokenUrl(
Typecho_Common::url('/member/profile', $this->options->index));
}
//在处理方法中首先验证`token`,保护提交数据的安全性
protected function profile(){
// protect
$this->security->protect();
//然后使用验证类验证数据完整性
$validator = new Typecho_Validate();
$validator->addRule('screenName', array($this, 'screenNameExists'), _t('昵称已经存在'));
//……
$error = $validator->run($this->request->from('screenName', 'mail', 'url'));
/** 截获验证异常 */
if ($error) {
/** 设置提示信息 */
$this->widget('Widget_Notice')->set($error,'error');
$this->response->goBack();
}
// 取出数据
$user = $this->request->from('mail', 'screenName', 'url');
$user['screenName'] = empty($user['screenName']) ? $user['name'] : $user['screenName'];
// 更新数据
$this->update($user, $this->db->sql()->where('uid = ?', $this->user->uid));
// 提示信息
$this->widget('Widget_Notice')->set(_t('您的档案已经更新'), 'success');
// 转向原页
$this->response->goBack();
}
这样就能够保存用户信息了;也可以在table.users
添加其他字段以实现更多的功能
登录路由
http://xxx/login/oauth?type={qq|weibo}
callback地址
http://xxx/login/oauth_callback
基本上都是关于各个sdk的使用,也不讲那些了
/**
* 查找绑定的用户
*
* @param stirng $openid 通过sdk获取到的openid
* @param string $type qq、weibo等
* @ return array 返回找到的用户或者0
*/
protected function findSnsUser($openid,$type){
//todo……
}
/**
* 使用查找到的绑定用户的信息登录
*
* @param array $user 用户数组
* @param int $expire cookie时间
* return null
*/
protected function snsLogin($user,$expire = 0){
//todo……
}
//……
通过sdk获取到用户的openid,在数据库中查找是否已经绑定:若已经绑定则直接登录;未绑定则注册为新用户
大概就是这个意思吧@_@
未完待续……
评论已关闭