威宁热线

威宁团菜到家

[技术分享] Discuz!注册页面修改增加记录推荐人账号

[复制链接]
威宁热线 发表于 2021-1-27 16:42:23 | 显示全部楼层 |阅读模式
注册入口地址为:member.php?mod=register
一.member.php:
打开之后,代码非常简单。
其中有一句:
  1. $mod = !in_array($discuz->var['mod'], $modarray) && (!preg_match('/^\w+$/', $discuz->var['mod']) || !file_exists(DISCUZ_ROOT.'./source/module/member/member_'.$discuz->var['mod'].'.php')) ? 'register' : $discuz->var['mod'];
复制代码
这一句里面的 $discuz->var['mod']来源
  1. require libfile('function/member');//载入menber 函数
  2. require libfile('class/member');//载入menber 类库
  3. runhooks();  //运行hook点
复制代码
require DISCUZ_ROOT.'./source/module/member/member_'.$mod.'.php';//载入member_register.php页面。
从这里面来看,主要注册程序页为:source/module/member/member_register.php页面。
二.source/module/member/member_register.php:
  1. if(!defined('IN_DISCUZ')) {
  2.     exit('Access Denied');
  3. }//来源检测

  4. define('NOROBOT', TRUE);
复制代码
  1. $ctl_obj = new register_ctl();//实例化register_ctl类
  2. $ctl_obj->setting = $_G['setting'];//获取全局变量中setting值
  3. $ctl_obj->template = 'member/register';//载入模板template\default\member\register.htm
  4. $ctl_obj->on_register();//执行on_register函数
复制代码
注册执行的主函数为:register_ctl类中的on_register(),register_ctl类的位置是:source/class/class_member.php文件中。这个文件在第一部分已经通过载入类库方式载入。

三.source/class/class_member.php:
  1. function register_ctl(){}
  2. function on_register(){}
复制代码
这个文件只有这两个函数,register_ctl(){}初始化,载入相关类库。on_register()注册程序。
注册程序很长,选几个关键点来看:
大约700行左右(这个程序页面我稍微修改过,跟官方原版略有区别):
  1. if(!$activation) {
  2.                 $ffromuser=getuserbyuid($fromuid);//这个系我添加,上面程序已经获取了$fromuid推荐人ID,这里我获取了一下推荐人的数据(注:这是个人员数据数组对象, $ffromuser['username']是用户名)。
  3.                 $uid = uc_user_register(addslashes($username), $password, $email, $questionid, $answer, $_G['clientip'], $ffromuser['username']);//ucenter中心添加用户。
  4. 这个程序uc_user_register()是添加用户的具体实现方法。
  5. uc_user_register()这个程序的位置是:uc_client\client.php页面里面。
  6. 四.uc_client\client.php:
  7. function uc_user_register($username, $password, $email, $questionid = '', $answer = '', $regip = '',$fromuser = '') {
  8.     return call_user_func(UC_API_FUNC, 'user', 'register', array('username'=>$username, 'password'=>$password, 'email'=>$email, 'questionid'=>$questionid, 'answer'=>$answer, 'regip'=>$regip, 'fromuser'=>$fromuser));
  9. }
复制代码
代码很简单,调用了call_user_func()方法实现了多接口复用。其中参数:
UC_API_FUNC参数在该页面头部定义了:
  1. define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post');//在我这边连接方式是mysql,根据配置,也可以使用api post方式传送用户注册信息。
复制代码
uc_api_mysql()函数,在本页面上部定义了:
  1. function uc_api_mysql($model, $action, $args=array()) {
  2.     global $uc_controls;
  3.     if(empty($uc_controls[$model])) {
  4.         if(function_exists("mysql_connect")) {
  5.             include_once UC_ROOT.'./lib/db.class.php';
  6.         } else {
  7.             include_once UC_ROOT.'./lib/dbi.class.php';
  8.         }
  9.         include_once UC_ROOT.'./model/base.php';
  10.         include_once UC_ROOT."./control/$model.php";
  11.         eval("\$uc_controls['$model'] = new {$model}control();");
  12.     }
  13.     if($action{0} != '_') {
  14.         $args = uc_addslashes($args, 1, TRUE);
  15.         $action = 'on'.$action;
  16.         $uc_controls[$model]->input = $args;
  17.         return $uc_controls[$model]->$action($args);
  18.     } else {
  19.         return '';
  20.     }
  21. }
  22. include_once UC_ROOT."./control/$model.php";表示载入/control/user.php模块。
  23. $action = 'on'.$action;表示调用函数onregister();
复制代码
五.uc_client\control\user.php:
  1. function onregister() {
  2.         $this->init_input();
  3.         $username = $this->input('username');
  4.         $password =  $this->input('password');
  5.         $email = $this->input('email');
  6.         $questionid = $this->input('questionid');
  7.         $answer = $this->input('answer');
  8.         $regip = $this->input('regip');
  9.         $fromuser = $this->input('fromuser');//这一行是我添加的推荐人信息。

  10.         if(($status = $this->_check_username($username)) < 0) {
  11.             return $status;
  12.         }
  13.         if(($status = $this->_check_email($email)) < 0) {
  14.             return $status;
  15.         }
  16.         $uid = $_ENV['user']->add_user($username, $password, $email, 0, $questionid, $answer, $regip, $fromuser);//这一行是我修改的推荐人账号传参。
  17.         return $uid;
  18.     }
复制代码
$_ENV是PHP中的一个包含服务器端环境变量的数组。它是PHP中一个超级全局变量,我们可以在PHP程序的任何地方直接访问它。
在 uc_client/model/base.php 中,使用了load()方法定义了 $_ENV[$model] 并赋值。
  1. function load($model, $base = NULL) {
  2.     $base = $base ? $base : $this;
  3.     if(empty($_ENV[$model])) {
  4.         require_once UC_ROOT."./model/$model.php";
  5.         eval('$_ENV[$model] = new '.$model.'model($base);');
  6.     }
  7.     return $_ENV[$model];
  8. }
复制代码
这里的作用,我们不深究,知道这里调用的是UC_ROOT."./model/user.php中的add_user()方法。

六.uc_client/model/user.php:
大约L129:
  1. function add_user($username, $password, $email, $uid = 0, $questionid = '', $answer = '', $regip = '', $fromuser = '') {        
  2.         $regip = empty($regip) ? $this->base->onlineip : $regip;
  3.         $salt = substr(uniqid(rand()), -6);
  4.         $password = md5(md5($password).$salt);
  5.         $sqladd = $uid ? "uid='".intval($uid)."'," : '';
  6.         $sqladd .= $questionid > 0 ? " secques='".$this->quescrypt($questionid, $answer)."'," : " secques='',";
  7.         $this->db->query("INSERT INTO ".UC_DBTABLEPRE."members SET $sqladd username='$username', password='$password', email='$email', regip='$regip', regdate='".$this->base->time."', salt='$salt'");
  8.         $uid = $this->db->insert_id();
  9.         $this->db->query("INSERT INTO ".UC_DBTABLEPRE."memberfields SET uid='$uid'");
  10.         return $uid;
  11.     }
复制代码
到此,参数就传递到写入数据库的部分了,具体如何放置就不属于本文讨论范围,相信大家会有很多很好的解决方案。
所有需要修改的部分就完成了。总共涉及6个页面。


回复

使用道具 举报

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

本版积分规则

快速回复 返回顶部 返回列表