1155 lines
38 KiB
PHP
1155 lines
38 KiB
PHP
<?php namespace Phpcmf\Model;
|
||
/**
|
||
* https://www.besyun.com
|
||
* BESCMS
|
||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||
**/
|
||
|
||
class Member extends \Phpcmf\Model {
|
||
|
||
protected $sso_url;
|
||
|
||
/**
|
||
* 由用户名获取uid
|
||
*/
|
||
public function uid($name) {
|
||
|
||
if (!$name || dr_lang('游客') == $name) {
|
||
return 0;
|
||
} elseif ($name == $this->member['username']) {
|
||
return $this->member['uid'];
|
||
}
|
||
|
||
$data = $this->db->table('member')
|
||
->select('id')
|
||
->where('username', dr_safe_replace($name))
|
||
->get()->getRowArray();
|
||
|
||
return intval($data['id']);
|
||
}
|
||
|
||
/**
|
||
* 由uid获取用户名
|
||
*/
|
||
public function username($uid) {
|
||
|
||
$uid = intval($uid);
|
||
|
||
if (!$uid) {
|
||
return '';
|
||
} elseif ($uid == $this->member['uid']) {
|
||
return $this->member['username'];
|
||
}
|
||
|
||
$data = $this->db->table('member')
|
||
->select('username')
|
||
->where('id', $uid)
|
||
->get()->getRowArray();
|
||
|
||
return $data['username'];
|
||
}
|
||
|
||
/**
|
||
* 后台账号字段获取用户名
|
||
*/
|
||
public function author($uid) {
|
||
|
||
if (!$uid) {
|
||
return dr_lang('游客');
|
||
}
|
||
|
||
return $this->username($uid);
|
||
}
|
||
|
||
/**
|
||
* 由uid获取电话
|
||
*/
|
||
public function phone($uid) {
|
||
|
||
$uid = intval($uid);
|
||
if (!$uid) {
|
||
return '';
|
||
} elseif ($uid == $this->member['uid']) {
|
||
return $this->member['phone'];
|
||
}
|
||
|
||
$data = $this->db->table('member')
|
||
->select('phone')
|
||
->where('id', $uid)
|
||
->get()->getRowArray();
|
||
|
||
return $data['phone'];
|
||
}
|
||
|
||
// 用户基本信息
|
||
public function member_info($uid) {
|
||
|
||
$uid = intval($uid);
|
||
if (!$uid) {
|
||
return [];
|
||
} elseif ($uid == $this->member['uid']) {
|
||
return $this->member;
|
||
}
|
||
|
||
$data = $this->db->table('member')
|
||
->where('id', $uid)
|
||
->get()->getRowArray();
|
||
if (!$data) {
|
||
return [];
|
||
}
|
||
|
||
$data['uid'] = $data['id'];
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* 登录记录
|
||
*
|
||
* @param intval $data 会员
|
||
* @param string $OAuth 登录方式
|
||
*/
|
||
protected function _login_log($data, $type = '') {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
return;
|
||
}
|
||
|
||
\Phpcmf\Service::M('member', 'member')->_login_log($data, $type);
|
||
}
|
||
|
||
/**
|
||
* 取会员COOKIE
|
||
*/
|
||
public function member_uid() {
|
||
|
||
// 获取本地cookie
|
||
$uid = (int)\Phpcmf\Service::L('input')->get_cookie('member_uid');
|
||
if (!$uid) {
|
||
return 0;
|
||
}
|
||
|
||
return $uid;
|
||
}
|
||
|
||
|
||
/**
|
||
* 初始化处理
|
||
*/
|
||
public function init_member($member) {
|
||
|
||
if (!$member || !IS_USE_MEMBER) {
|
||
return;
|
||
}
|
||
|
||
|
||
\Phpcmf\Service::M('member', 'member')->init_member($member);
|
||
}
|
||
|
||
/**
|
||
* 存储cookie
|
||
*/
|
||
public function save_cookie($data, $remember = 0) {
|
||
|
||
// 存储cookie
|
||
$expire = $remember ? 8640000 : SITE_LOGIN_TIME;
|
||
\Phpcmf\Service::L('input')->set_cookie('member_uid', $data['id'], $expire);
|
||
\Phpcmf\Service::L('input')->set_cookie('member_cookie', md5(SYS_KEY.$data['password'].(isset($data['login_attr']) ? $data['login_attr'] : '')), $expire);
|
||
|
||
// 登录后的钩子,在_login_log中执行他
|
||
//\Phpcmf\Hooks::trigger('member_login_after', $data);
|
||
|
||
$this->clear_cache($data['id']);
|
||
}
|
||
|
||
/**
|
||
* 验证会员有效性 1表示通过 0表示不通过
|
||
*/
|
||
public function check_member_cookie($member) {
|
||
|
||
// 获取本地认证cookie
|
||
$cookie = \Phpcmf\Service::L('input')->get_cookie('member_cookie');
|
||
|
||
// 授权登陆时不验证
|
||
if ($member['id'] && \Phpcmf\Service::C()->session()->get('member_auth_uid') == $member['id']) {
|
||
return 1;
|
||
} elseif (!$cookie) {
|
||
return 0;
|
||
} elseif (md5(SYS_KEY.$member['password'].(isset($member['login_attr']) ? $member['login_attr'] : '')) != $cookie) {
|
||
return 0;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* 授权登录信息
|
||
*/
|
||
public function oauth($uid) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
return [];
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->oauth($uid);
|
||
}
|
||
|
||
/**
|
||
* 会员信息
|
||
*/
|
||
public function get_member($uid = 0, $name = '') {
|
||
|
||
$uid = intval($uid);
|
||
if ($uid && $uid == $this->member['id']) {
|
||
return $this->member;
|
||
}
|
||
|
||
if ($uid) {
|
||
$data = $this->db->table('member')->where('id', $uid)->get()->getRowArray();
|
||
} elseif ($name) {
|
||
$data = $this->db->table('member')->where('username', $name)->get()->getRowArray();
|
||
$uid = (int)$data['id'];
|
||
} else {
|
||
return null;
|
||
}
|
||
|
||
if (!$data) {
|
||
return null;
|
||
}
|
||
|
||
// 附表字段
|
||
$data2 = $this->db->table('member_data')->where('id', $uid)->get()->getRowArray();
|
||
$data2 && $data = dr_array2array($data, \Phpcmf\Service::L('Field')->app('member')->format_value(\Phpcmf\Service::C()->member_cache['field'], $data2));
|
||
|
||
$data['uid'] = $data['id'];
|
||
$data['avatar'] = dr_avatar($data['id']);
|
||
$data['adminid'] = (int)$data['is_admin'];
|
||
//$data['tableid'] = (int)substr((string)$data['id'], -1, 1);
|
||
|
||
$data['group'] = $data['groupid'] = $data['levelid'] = $data['authid'] = $data['group_name'] = [];
|
||
$data['group_timeout'] = 0;
|
||
|
||
// 会员组信息
|
||
if (IS_USE_MEMBER) {
|
||
if (!is_file(IS_USE_MEMBER.'Models/Member.php')) {
|
||
exit('需要离线下载【用户系统】插件,然后手动覆盖到本站:https://www.xunruicms.com/doc/1220.html');
|
||
}
|
||
$data = \Phpcmf\Service::M('member', 'member')->get_member_group($data);
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
// 获取authid
|
||
public function authid($uid) {
|
||
if (IS_USE_MEMBER) {
|
||
return \Phpcmf\Service::M('member', 'member')->authid($uid);
|
||
}
|
||
}
|
||
|
||
// 更新用户组
|
||
// member 用户信息
|
||
// groups 拥有的用户组
|
||
public function update_group($member, $groups) {
|
||
|
||
$g = [];
|
||
if (!$member || !$groups) {
|
||
return $g;
|
||
} elseif (IS_USE_MEMBER) {
|
||
return \Phpcmf\Service::M('member', 'member')->update_group($member, $groups);
|
||
}
|
||
|
||
return $g;
|
||
}
|
||
|
||
// 删除用户组 is_admin 是否是管理员删除,否则就是过期删除
|
||
public function delete_group($uid, $gid, $is_admin = 1) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:delete_group');
|
||
return false;
|
||
}
|
||
|
||
\Phpcmf\Service::M('member', 'member')->delete_group($uid, $gid, $is_admin);
|
||
}
|
||
|
||
// 新增用户组
|
||
public function insert_group($uid, $gid, $is_notice = 1) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:insert_group');
|
||
return false;
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->insert_group($uid, $gid, $is_notice);
|
||
}
|
||
|
||
// 手动变更等级
|
||
public function update_level($uid, $gid, $lid) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:update_level');
|
||
return false;
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->update_level($uid, $gid, $lid);
|
||
}
|
||
|
||
// 申请用户组
|
||
public function apply_group($verify_id, $member, $gid, $lid, $price, $my_verify) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:apply_group');
|
||
return false;
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->apply_group($verify_id, $member, $gid, $lid, $price, $my_verify);
|
||
}
|
||
|
||
/**
|
||
* 添加一条通知
|
||
*
|
||
* @param string $uid
|
||
* @param string $note
|
||
* @return null
|
||
*/
|
||
public function notice($uid, $type, $note, $url = '', $mark = '') {
|
||
|
||
if (!$uid || !$note) {
|
||
return '';
|
||
}
|
||
|
||
if (dr_is_app('notice')) {
|
||
\Phpcmf\Service::M('notice', 'notice')->add_notice($uid, $type, $note, $url, $mark);
|
||
}
|
||
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* 系统提醒
|
||
*
|
||
* @param site 站点id,公共部分0
|
||
* @param type system系统 content内容相关 member会员相关 app应用相关 pay 交易相关
|
||
* @param msg 提醒内容
|
||
* @param uri 后台对应的链接
|
||
* @param to 通知对象 留空表示全部对象
|
||
* array(
|
||
* to_uid 指定人
|
||
* to_rid 指定角色组
|
||
* )
|
||
*/
|
||
public function admin_notice($site, $type, $member, $msg, $uri, $to = []) {
|
||
\Phpcmf\Service::M('auth')->notice($site, $type, $member, $msg, $uri, $to);
|
||
}
|
||
|
||
// 执行提醒
|
||
public function todo_admin_notice($uri, $site = 0) {
|
||
\Phpcmf\Service::M('auth')->todo_notice($uri, $site);
|
||
}
|
||
|
||
// 执行删除提醒
|
||
public function delete_admin_notice($uri, $site = 0) {
|
||
\Phpcmf\Service::M('auth')->delete_notice($uri, $site);
|
||
}
|
||
|
||
// 审核用户
|
||
public function verify_member($uid) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:verify_member');
|
||
return false;
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->verify_member($uid);
|
||
}
|
||
|
||
// 获取本站通讯地址
|
||
public function get_sso_url() {
|
||
|
||
if ($this->sso_url) {
|
||
return $this->sso_url;
|
||
}
|
||
|
||
$this->sso_url = [];
|
||
|
||
if (is_file(WRITEPATH.'config/domain_sso.php')) {
|
||
$sso = require WRITEPATH.'config/domain_sso.php';
|
||
$rts = [];
|
||
foreach ($sso as $u) {
|
||
list($a) = explode(',', $u);
|
||
if (in_array($a, $rts)) {
|
||
continue;
|
||
}
|
||
$rts[] = $a;
|
||
$this->sso_url[] = $u ? dr_http_prefix($u).'/' : '/';
|
||
}
|
||
}
|
||
|
||
return $this->sso_url;
|
||
}
|
||
|
||
/**
|
||
* sso 登录url
|
||
*/
|
||
public function sso($data, $remember = 0) {
|
||
|
||
$sso = [];
|
||
$url = $this->get_sso_url();
|
||
foreach ($url as $u) {
|
||
$code = dr_authcode($data['id'].'-'.$data['salt'], 'ENCODE');
|
||
$sso[]= $u.'index.php?s=api&c=sso&action=login&remember='.$remember.'&code='.$code;
|
||
}
|
||
|
||
return $sso;
|
||
}
|
||
|
||
/**
|
||
* 前端会员退出登录
|
||
*/
|
||
public function logout() {
|
||
|
||
\Phpcmf\Hooks::trigger('member_logout', $this->member);
|
||
|
||
\Phpcmf\Service::L('input')->set_cookie('member_uid', 0, -100000000);
|
||
\Phpcmf\Service::L('input')->set_cookie('member_cookie', '', -100000000);
|
||
\Phpcmf\Service::L('input')->set_cookie('admin_login_member', '', -100000000);
|
||
|
||
$sso = [];
|
||
$url = $this->get_sso_url();
|
||
foreach ($url as $u) {
|
||
$sso[]= $u.'index.php?s=api&c=sso&action=logout';
|
||
}
|
||
|
||
return $sso;
|
||
}
|
||
|
||
// 查询会员信息
|
||
protected function _find_member_info($username) {
|
||
|
||
$data = $this->db->table('member')->where('username', $username)->get()->getRowArray();
|
||
if (!$data && \Phpcmf\Service::C()->member_cache['login']['field']) {
|
||
if (dr_in_array('email', \Phpcmf\Service::C()->member_cache['login']['field'])
|
||
&& \Phpcmf\Service::L('Form')->check_email($username)) {
|
||
$data = $this->db->table('member')->where('email', $username)->get()->getRowArray();
|
||
} elseif (dr_in_array('phone', \Phpcmf\Service::C()->member_cache['login']['field'])
|
||
&& \Phpcmf\Service::L('Form')->check_phone($username)) {
|
||
$data = $this->db->table('member')->where('phone', $username)->get()->getRowArray();
|
||
}
|
||
}
|
||
|
||
if (!$data) {
|
||
return [];
|
||
}
|
||
|
||
$data['uid'] = $data['id'];
|
||
|
||
return $data;
|
||
}
|
||
|
||
// 验证管理员登录权限
|
||
protected function _is_admin_login_member($uid) {
|
||
|
||
if (!$uid) {
|
||
return dr_return_data(1, 'ok');
|
||
}
|
||
|
||
if (!\Phpcmf\Service::C()->member_cache['login']['admin']
|
||
&& $this->db->table('admin')->where('uid', $uid)->countAllResults()) {
|
||
return dr_return_data(0, dr_lang('管理员账号不允许前台登录'));
|
||
}
|
||
|
||
return dr_return_data(1, 'ok');
|
||
}
|
||
|
||
/**
|
||
* 验证登录
|
||
*
|
||
* @param string $username 用户名
|
||
* @param string $password 明文密码
|
||
* @param intval $remember 是否记住密码
|
||
*/
|
||
public function login($username, $password, $remember = 0) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:login');
|
||
return dr_return_data(0, dr_lang('没有安装【用户系统】插件'));
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->login($username, $password, $remember);
|
||
}
|
||
|
||
// 短信登录
|
||
public function login_sms($phone, $remember) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:login_sms');
|
||
return dr_return_data(0, dr_lang('没有安装【用户系统】插件'));
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->login_sms($phone, $remember);
|
||
}
|
||
|
||
// 授权登录
|
||
public function login_oauth($name, $data) {
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($data);
|
||
|
||
// 记录日志
|
||
$this->_login_log($data, $name);
|
||
|
||
return $this->sso($data);
|
||
}
|
||
|
||
// 绑定注册模式 授权注册绑定
|
||
public function register_oauth_bang($oauth, $groupid, $member, $data = []) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:register_oauth_bang');
|
||
return dr_return_data(0, dr_lang('没有安装【用户系统】插件'));
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->register_oauth_bang($oauth, $groupid, $member, $data);
|
||
}
|
||
|
||
// api直接按uid登录
|
||
public function login_uid($oauth, $uid) {
|
||
|
||
$member = $this->get_member($uid);
|
||
if (!$member) {
|
||
return dr_return_data(0, dr_lang('用户不存在'));
|
||
}
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($member);
|
||
|
||
// 记录日志
|
||
$this->_login_log($member, $oauth['oauth']);
|
||
|
||
return dr_return_data($member['id'], dr_lang('登录成功'), [
|
||
'auth'=> md5($member['password'].$member['salt']), // API认证字符串,
|
||
'member' => $member,
|
||
]);
|
||
}
|
||
|
||
// 直接登录模式 授权注册
|
||
public function register_oauth($groupid, $oauth) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:register_oauth_bang');
|
||
return dr_return_data(0, dr_lang('没有安装【用户系统】插件'));
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->register_oauth($groupid, $oauth);
|
||
}
|
||
|
||
/**
|
||
* 用户注册
|
||
*
|
||
* @param 用户组
|
||
* @param 注册账户信息
|
||
* @param 自定义字段信息
|
||
* @param 快捷登录注册
|
||
*/
|
||
public function register($groupid, $member, $data = [], $oauth = []) {
|
||
|
||
$member['email'] && $member['email'] = strtolower($member['email']);
|
||
$member['name'] = htmlspecialchars(!$member['name'] ? '' : dr_strcut($member['name'], intval(\Phpcmf\Service::C()->member_cache['register']['cutname']), ''));
|
||
|
||
// 没有账号,随机一个默认登录账号
|
||
if (!$member['username']) {
|
||
$member['username'] = $this->_register_rand_username($member);
|
||
// 随机账号不满足规范时
|
||
} else {
|
||
$member['username'] = strtolower(dr_safe_filename($member['username']));
|
||
}
|
||
|
||
$member['salt'] = substr(md5(rand(0, 999)), 0, 10); // 随机10位密码加密码
|
||
|
||
// 默认注册组
|
||
!$groupid && $groupid = (int)\Phpcmf\Service::C()->member_cache['register']['groupid'];
|
||
|
||
if ((\Phpcmf\Service::C()->member_cache['oauth']['login'] || !\Phpcmf\Service::C()->member_cache['oauth']['field']) && $oauth) {
|
||
// 授权登录直接模式
|
||
if ($member['username'] && dr_in_array('username', \Phpcmf\Service::C()->member_cache['register']['field'])) {
|
||
// 验证账号是否规范
|
||
$rt = \Phpcmf\Service::L('Form')->check_username($member['username']);
|
||
if (!$rt['code']) {
|
||
$member['username'] = $this->_register_rand_username($member);
|
||
}
|
||
}
|
||
if ($member['name'] && \Phpcmf\Service::C()->member_cache['config']['unique_name']
|
||
&& $this->db->table('member')->where('name', $member['name'])->countAllResults()) {
|
||
$member['name'] = $member['name'].'_XR_RAND_';
|
||
}
|
||
} else {
|
||
// 验证格式
|
||
if ($member['username'] && dr_in_array('username', \Phpcmf\Service::C()->member_cache['register']['field'])) {
|
||
$rt = \Phpcmf\Service::L('Form')->check_username($member['username']);
|
||
if (!$rt['code']) {
|
||
return $rt;
|
||
}
|
||
}
|
||
$is_email_y = 1;
|
||
$is_phone_y = 1;
|
||
if (isset(\Phpcmf\Service::C()->member_cache['register']['field_y'])
|
||
&& is_array(\Phpcmf\Service::C()->member_cache['register']['field_y'])) {
|
||
$is_email_y = in_array('email', \Phpcmf\Service::C()->member_cache['register']['field_y']);
|
||
$is_phone_y = in_array('phone', \Phpcmf\Service::C()->member_cache['register']['field_y']);
|
||
}
|
||
if ($is_email_y && $member['email'] && dr_in_array('email', \Phpcmf\Service::C()->member_cache['register']['field'])
|
||
&& !\Phpcmf\Service::L('Form')->check_email($member['email'])) {
|
||
return dr_return_data(0, dr_lang('邮箱格式不正确'), ['field' => 'email']);
|
||
}
|
||
if ($is_phone_y && $member['phone'] && dr_in_array('phone', \Phpcmf\Service::C()->member_cache['register']['field'])
|
||
&& !\Phpcmf\Service::L('Form')->check_phone($member['phone'])) {
|
||
return dr_return_data(0, dr_lang('手机号码格式不正确'), ['field' => 'phone']);
|
||
}
|
||
// 前端验证密码格式
|
||
if (!IS_ADMIN) {
|
||
if ($member['password'] == SYS_KEY.'_login_sms') {
|
||
$member['salt'] = 'login_sms';
|
||
$member['password'] = rand(0, 99999); // 表示短信直接注册
|
||
} else {
|
||
$rt = \Phpcmf\Service::L('Form')->check_password($member['password'], $member['username']);
|
||
if (!$rt['code']) {
|
||
return $rt;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 验证唯一性
|
||
if ($member['username'] && $this->db->table('member')->where('username', $member['username'])->countAllResults()) {
|
||
return dr_return_data(0, dr_lang('账号已经注册'), ['field' => 'username']);
|
||
} elseif ($member['email'] && $this->db->table('member')->where('email', $member['email'])->countAllResults()) {
|
||
return dr_return_data(0, dr_lang('邮箱已经注册'), ['field' => 'email']);
|
||
} elseif ($member['phone'] && $this->db->table('member')->where('phone', $member['phone'])->countAllResults()) {
|
||
return dr_return_data(0, dr_lang('手机号码已经注册'), ['field' => 'phone']);
|
||
} elseif ($member['name'] && \Phpcmf\Service::C()->member_cache['config']['unique_name']
|
||
&& $this->db->table('member')->where('name', $member['name'])->countAllResults()) {
|
||
return dr_return_data(0, dr_lang('%s已经注册', MEMBER_CNAME), ['field' => 'name']);
|
||
}
|
||
|
||
if ($member['username'] == 'guest') {
|
||
return dr_return_data(0, dr_lang('此名称guest系统不允许注册'), ['field' => 'username']);
|
||
}
|
||
}
|
||
/*
|
||
elseif (!IS_ADMIN && \Phpcmf\Service::C()->member_cache['register']['notallow']) {
|
||
foreach (\Phpcmf\Service::C()->member_cache['register']['notallow'] as $mt) {
|
||
if ($mt && stripos($member['username'], $mt) !== false) {
|
||
return dr_return_data(0, dr_lang('账号[%s]禁止包含关键字[%s]', $member['username'], $mt), ['field' => 'username']);
|
||
}
|
||
}
|
||
}*/
|
||
|
||
$member['password'] = $member['password'] ? md5(md5($member['password']).$member['salt'].md5($member['password'])) : '';
|
||
$member['login_attr'] = '';
|
||
$member['money'] = 0;
|
||
$member['freeze'] = 0;
|
||
$member['spend'] = 0;
|
||
$member['score'] = 0;
|
||
$member['experience'] = 0;
|
||
$member['regip'] = $oauth ? '' : \Phpcmf\Service::L('input')->ip_info(); // 快捷登录时不记录ip
|
||
$member['regtime'] = SYS_TIME;
|
||
$member['randcode'] = \Phpcmf\Service::L('form')->get_rand_value();
|
||
|
||
// 防止重复账号
|
||
if ($member['username'] && $this->db->table('member')->where('username', $member['username'])->countAllResults()) {
|
||
$member['username'] = '';
|
||
}
|
||
|
||
$rt = $this->table('member')->insert($member);
|
||
if (!$rt['code']) {
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
|
||
$update = [];
|
||
// 姓名随机替换
|
||
if (\Phpcmf\Service::C()->member_cache['config']['unique_name'] && strpos($member['name'], '_XR_RAND_')) {
|
||
$update['name'] = str_replace( '_XR_RAND_', intval($rt['code']+date('Ymd')), $member['name']);
|
||
}
|
||
// 再次判断没有账号,随机一个默认登录账号
|
||
if (!$member['username']) {
|
||
$member['username'] = '';
|
||
if (isset(\Phpcmf\Service::C()->member_cache['register']['unprefix']) && \Phpcmf\Service::C()->member_cache['register']['unprefix']) {
|
||
$member['username'] = strtolower(trim((string)\Phpcmf\Service::C()->member_cache['register']['unprefix']));
|
||
}
|
||
$member['username'].= intval($rt['code']+date('Ymd'));
|
||
$update['username'] = $member['username'];
|
||
}
|
||
// 更新操作
|
||
$update && $this->table('member')->update($rt['code'], $update);
|
||
|
||
// 附表信息
|
||
$data['id'] = $member['uid'] = $member['id'] = $uid = $rt['code'];
|
||
$data['is_admin'] = 0;
|
||
$data['is_avatar'] = 0;
|
||
// 审核状态值
|
||
if (IS_ADMIN) {
|
||
$status = \Phpcmf\Service::L('input')->post('status');
|
||
$data['is_lock'] = isset($status['is_lock']) ? intval($status['is_lock']) : 0;
|
||
$data['is_email'] = isset($status['is_email']) ? intval($status['is_email']) : 0;
|
||
$data['is_verify'] = isset($status['is_verify']) ? intval($status['is_verify']) : 0;
|
||
$data['is_mobile'] = isset($status['is_mobile']) ? intval($status['is_mobile']) : 0;
|
||
} else {
|
||
$data['is_lock'] = 0;
|
||
$data['is_email'] = 0;
|
||
$data['is_verify'] = \Phpcmf\Service::C()->member_cache['register']['verify'] ? 0 : 1;
|
||
$data['is_mobile'] = 0;
|
||
}
|
||
$data['is_complete'] = 0;
|
||
$rt = $this->table('member_data')->replace($data);
|
||
if (!$rt['code']) {
|
||
// 删除主表
|
||
$this->table('member')->delete($uid);
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
|
||
// 归属用户组
|
||
if (IS_USE_MEMBER) {
|
||
$lid = 0;
|
||
if (\Phpcmf\Service::C()->member_cache['group'][$groupid]['level']) {
|
||
$level = \Phpcmf\Service::C()->member_cache['group'][$groupid]['level'];
|
||
$one = array_shift($level);
|
||
$lid = $one['id'];
|
||
}
|
||
$this->apply_group(0, $member, $groupid, $lid, 0, ['content' => $data]);
|
||
}
|
||
|
||
// 组合字段信息
|
||
$data = dr_array22array($member, $data);
|
||
$data['oauth'] = $oauth;
|
||
$data['groupid'] = $groupid;
|
||
|
||
// 审核判断
|
||
if (!$data['is_verify']) {
|
||
switch (\Phpcmf\Service::C()->member_cache['register']['verify']) {
|
||
|
||
case 'phone':
|
||
$this->sendsms_code($member['phone'], $member['randcode']);
|
||
break;
|
||
|
||
case 'email':
|
||
$this->sendmail($member['email'], dr_lang('注册邮件验证'), 'member_verify.html', $data);
|
||
break;
|
||
}
|
||
// 发送审核提醒
|
||
IS_USE_MEMBER && $this->admin_notice(
|
||
0,
|
||
'member',
|
||
$member,
|
||
dr_lang('新会员【%s】注册审核', $member['username']),
|
||
'member/verify/index:field/id/keyword/'.$uid
|
||
);
|
||
}
|
||
|
||
// 注册后的通知
|
||
\Phpcmf\Service::L('notice')->send_notice('member_register', $data);
|
||
|
||
// 注册后的钩子
|
||
\Phpcmf\Hooks::trigger('member_register_after', $data);
|
||
|
||
// API认证字符串
|
||
$data['auth'] = md5($data['password'].$data['salt']);
|
||
|
||
// 记录日志
|
||
$this->_login_log($data);
|
||
|
||
return dr_return_data($data['id'], dr_lang('注册成功'), $data);
|
||
}
|
||
|
||
/**
|
||
* 存储授权信息
|
||
*/
|
||
public function insert_oauth($uid, $type, $data, $state = '', $back = '') {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:insert_oauth');
|
||
return dr_return_data(0, dr_lang('没有权限'));
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->insert_oauth($uid, $type, $data, $state, $back);
|
||
}
|
||
|
||
// 修改密码
|
||
public function edit_password($member, $password) {
|
||
|
||
$id = (int)$member['id'];
|
||
$password = dr_safe_password($password);
|
||
if (!$id || !$password) {
|
||
return false;
|
||
}
|
||
|
||
$update['salt'] = substr(md5(rand(0, 999)), 0, 10); // 随机10位密码加密码
|
||
$update['randcode'] = 0;
|
||
$update['password'] = md5(md5($password).$update['salt'].md5($password));
|
||
$this->db->table('member')->where('id', $id)->update($update);
|
||
|
||
$member['uid'] = $id;
|
||
$member['password_value'] = $password;
|
||
|
||
// 通知
|
||
\Phpcmf\Service::L('Notice')->send_notice('member_edit_password', $member);
|
||
// 钩子
|
||
\Phpcmf\Hooks::trigger('member_edit_password_after', $member);
|
||
|
||
$this->clear_cache($id);
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 邮件发送
|
||
*/
|
||
public function sendmail($tomail, $subject, $msg, $data = []) {
|
||
return \Phpcmf\Service::M('email')->sendmail($tomail, $subject, $msg, $data);
|
||
}
|
||
|
||
/**
|
||
* 短信发送验证码
|
||
*/
|
||
public function sendsms_code($mobile, $code) {
|
||
return $this->sendsms_text($mobile, $code, 'code');
|
||
}
|
||
|
||
/**
|
||
* 短信发送文本
|
||
*/
|
||
public function sendsms_text($mobile, $content, $type = 'text') {
|
||
|
||
if (!$mobile || !$content) {
|
||
return dr_return_data(0, dr_lang('手机号码或内容不能为空'));
|
||
}
|
||
|
||
// 发送间隔
|
||
$interval = defined('SYS_CACHE_SMS') && SYS_CACHE_SMS ? (int) SYS_CACHE_SMS : 60;
|
||
if ($interval < 1) {
|
||
$interval = 60;
|
||
}
|
||
$need_limit = !IS_ADMIN && !(defined('IS_CLI') && IS_CLI);
|
||
$mobile_key = 'sms-send-mobile-' . md5((string) $mobile);
|
||
$http_key = (defined('USER_HTTP_CODE') && USER_HTTP_CODE) ? ('sms-send-http-' . USER_HTTP_CODE) : '';
|
||
if ($need_limit) {
|
||
if (\Phpcmf\Service::L('cache')->check_auth_data($mobile_key, $interval)) {
|
||
return dr_return_data(0, dr_lang('已经发送稍后再试'));
|
||
}
|
||
if ($http_key && \Phpcmf\Service::L('cache')->check_auth_data($http_key, $interval)) {
|
||
return dr_return_data(0, dr_lang('已经发送稍后再试'));
|
||
}
|
||
}
|
||
|
||
$file = WRITEPATH.'config/sms.php';
|
||
if (!is_file($file)) {
|
||
log_message('error', '短信接口配置文件('.$file.')不存在');
|
||
return dr_return_data(0, dr_lang('接口配置文件不存在'));
|
||
}
|
||
|
||
$config = \Phpcmf\Service::R($file);
|
||
if (is_file(CONFIGPATH.'mysms.php')) {
|
||
require_once CONFIGPATH.'mysms.php';
|
||
}
|
||
|
||
$method = 'my_sendsms_'.$type;
|
||
if (function_exists($method)) {
|
||
$rt = call_user_func_array($method, [
|
||
$mobile,
|
||
$content,
|
||
isset($config['third']) ? $config['third'] : '',
|
||
]);
|
||
// 发送成功后写入间隔标记
|
||
if ($need_limit && is_array($rt) && !empty($rt['code'])) {
|
||
\Phpcmf\Service::L('cache')->set_auth_data($mobile_key, (string) SYS_TIME);
|
||
if ($http_key) {
|
||
\Phpcmf\Service::L('cache')->set_auth_data($http_key, (string) SYS_TIME);
|
||
}
|
||
}
|
||
return $rt;
|
||
} else {
|
||
$error = dr_lang('你没有定义短信接口');
|
||
@file_put_contents(WRITEPATH.'sms_log.txt', date('Y-m-d H:i:s').' ['.$mobile.'] ['.$error.'] ('.str_replace(array(chr(13), chr(10)), '', $content).')'.PHP_EOL, FILE_APPEND);
|
||
return dr_return_data(0, $error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 发送微信通知模板
|
||
*
|
||
* $uid 会员id
|
||
* $id 微信模板id
|
||
* $data 通知内容
|
||
* $url 详细地址
|
||
* $color top颜色
|
||
*/
|
||
public function weixin_template($uid, $id, $data, $url = '', $color = '') {
|
||
return $this->wexin_template($uid, $id, $data, $url, $color);
|
||
}
|
||
public function wexin_template($uid, $id, $data, $url = '', $color = '') {
|
||
|
||
if (dr_is_app('weixin')) {
|
||
\Phpcmf\Service::C()->init_file('weixin');
|
||
return \Phpcmf\Service::M('weixin', 'weixin')->send_template($uid, $id, $data, $url, $color);
|
||
} else {
|
||
return dr_return_data(0, '没有安装微信插件');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 增加经验
|
||
*
|
||
* @param intval $uid 会员id
|
||
* @param intval $value 分数变动值
|
||
* @param string $mark 标记
|
||
* @param string $note 备注
|
||
* @param intval $count 统计次数
|
||
* @return intval
|
||
*/
|
||
public function add_experience($uid, $val, $note = '', $url = '', $mark = '', $count = 0) {
|
||
|
||
if (!dr_is_app('explog')) {
|
||
return dr_return_data(0, '未安装explog插件');
|
||
}
|
||
|
||
return \Phpcmf\Service::M('exp', 'explog')->add_experience($uid, $val, $note, $url, $mark, $count);
|
||
}
|
||
|
||
/**
|
||
* 增加金币
|
||
*
|
||
* @param intval $uid 会员id
|
||
* @param intval $value 分数变动值
|
||
* @param string $mark 标记
|
||
* @param string $note 备注
|
||
* @param intval $count 统计次数
|
||
* @return intval
|
||
*/
|
||
public function add_score($uid, $val, $note = '', $url = '', $mark = '', $count = 0) {
|
||
|
||
if (!dr_is_app('scorelog')) {
|
||
return dr_return_data(0, '未安装scorelog插件');
|
||
}
|
||
|
||
return \Phpcmf\Service::M('score', 'scorelog')->add_score($uid, $val, $note, $url, $mark, $count);
|
||
}
|
||
|
||
// 增加money
|
||
public function add_money($uid, $value) {
|
||
|
||
$value = floatval($value);
|
||
if (!$value) {
|
||
return dr_return_data(0, dr_lang('金额不正确'));
|
||
}
|
||
|
||
$member = $this->member_info($uid);
|
||
if (!$member) {
|
||
return dr_return_data(0, dr_lang('用户不存在'));
|
||
}
|
||
|
||
$money = (float)$member['money'] + $value;
|
||
if ($money < 0) {
|
||
return dr_return_data(0, dr_lang('账户可用余额不足'));
|
||
}
|
||
|
||
$update = [
|
||
'money' => $money,
|
||
];
|
||
$value < 0 && $update['spend'] = max(0, (float)$member['spend'] + abs($value));
|
||
|
||
$rt = $this->table('member')->update($uid, $update);
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 冻结资金
|
||
public function add_freeze($uid, $value) {
|
||
|
||
$value = floatval(abs($value));
|
||
if (!$uid || !$value) {
|
||
return dr_return_data(0, dr_lang('参数不正确'));
|
||
}
|
||
|
||
$ok = $this->db->table('member')
|
||
->where('id', (int) $uid)
|
||
->set('money', 'money-'.$value, false)
|
||
->set('freeze', 'freeze+'.$value, false)
|
||
->update();
|
||
if (!$ok) {
|
||
$error = $this->db->error();
|
||
return $this->_return_error($error['message'] ?? '');
|
||
}
|
||
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
// 取消冻结资金
|
||
public function cancel_freeze($uid, $value) {
|
||
|
||
$value = floatval(abs($value));
|
||
if (!$uid || !$value) {
|
||
return dr_return_data(0, dr_lang('参数不正确'));
|
||
}
|
||
|
||
$ok = $this->db->table('member')
|
||
->where('id', (int) $uid)
|
||
->set('money', 'money+'.$value, false)
|
||
->set('freeze', 'freeze-'.$value, false)
|
||
->update();
|
||
if (!$ok) {
|
||
$error = $this->db->error();
|
||
return $this->_return_error($error['message'] ?? '');
|
||
}
|
||
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
// 使用消费资金
|
||
public function use_freeze($uid, $value) {
|
||
|
||
$value = floatval(abs($value));
|
||
if (!$uid || !$value) {
|
||
return dr_return_data(0, dr_lang('参数不正确'));
|
||
}
|
||
|
||
$ok = $this->db->table('member')
|
||
->where('id', (int) $uid)
|
||
->set('spend', 'spend+'.$value, false)
|
||
->set('freeze', 'freeze-'.$value, false)
|
||
->update();
|
||
if (!$ok) {
|
||
$error = $this->db->error();
|
||
return $this->_return_error($error['message'] ?? '');
|
||
}
|
||
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
// 删除会员后执行 sync是否删除相关数据表
|
||
public function member_delete($id, $sync = 0) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
log_message('debug', '没有安装【用户系统】插件,无法执行函数:member_delete');
|
||
return false;
|
||
}
|
||
|
||
return \Phpcmf\Service::M('member', 'member')->member_delete($id, $sync);
|
||
}
|
||
|
||
// 头像认证执行
|
||
public function do_avatar($member) {
|
||
|
||
if ($member['is_avatar'] || !IS_USE_MEMBER) {
|
||
return;
|
||
}
|
||
|
||
$this->db->table('member_data')->where('id', $member['id'])->update(['is_avatar' => 1]);
|
||
|
||
// avatar_score
|
||
$value = \Phpcmf\Service::L('member_auth', 'member')->member_auth('avatar_score', $member);
|
||
if ($value) {
|
||
\Phpcmf\Service::M('member')->add_experience($member['id'], $value, dr_lang('头像认证'), '', 'avatar_score', 1);
|
||
}
|
||
|
||
$value = \Phpcmf\Service::L('member_auth', 'member')->member_auth('avatar_exp', $member);
|
||
if ($value) {
|
||
$this->add_score($member['id'], $value, dr_lang('头像认证'), '', 'avatar_exp', 1);
|
||
}
|
||
}
|
||
|
||
// 注册随机账号
|
||
protected function _register_rand_username($member, $ct = 0) {
|
||
|
||
if ($member['email']) {
|
||
list($name) = explode('@', $member['email']);
|
||
} elseif ($member['phone']) {
|
||
$name = substr($member['phone'], 5);
|
||
} elseif ($member['name']) {
|
||
$name = \Phpcmf\Service::L('pinyin')->result(dr_clear_emoji($member['name']));
|
||
if ($name) {
|
||
$name = urlencode((string)$name);
|
||
$name = preg_replace("/(%7E|%60|%21|%40|%23|%24|%25|%5E|%26|%27|%2A|%28|%29|%2B|%7C|%5C|%3D|\-|_|%5B|%5D|%7D|%7B|%3B|%22|%3A|%3F|%3E|%3C|%2C|\.|%2F|%A3%BF|%A1%B7|%A1%B6|%A1%A2|%A1%A3|%A3%AC|%7D|%A1%B0|%A3%BA|%A3%BB|%A1%AE|%A1%AF|%A1%B1|%A3%FC|%A3%BD|%A1%AA|%A3%A9|%A3%A8|%A1%AD|%A3%A4|%A1%A4|%A3%A1|%E3%80%82|%EF%BC%81|%EF%BC%8C|%EF%BC%9B|%EF%BC%9F|%EF%BC%9A|%E3%80%81|%E2%80%A6%E2%80%A6|%E2%80%9D|%E2%80%9C|%E2%80%98|%E2%80%99)+/",'', $name);
|
||
$name = urldecode($name);
|
||
}
|
||
}
|
||
|
||
if (!$name || $ct > 5) {
|
||
return '';
|
||
}
|
||
|
||
// 重复名称加随机数
|
||
$ct && $name.= $ct + rand(0, 999);
|
||
|
||
// 最大位数
|
||
if (\Phpcmf\Service::C()->member_cache['config']['userlenmax']
|
||
&& mb_strlen($name) > (int)\Phpcmf\Service::C()->member_cache['config']['userlenmax']) {
|
||
$name = dr_strcut($name, (int)\Phpcmf\Service::C()->member_cache['config']['userlenmax'], '');
|
||
}
|
||
|
||
// 增加用户名前缀
|
||
if (isset(\Phpcmf\Service::C()->member_cache['register']['unprefix'])
|
||
&& \Phpcmf\Service::C()->member_cache['register']['unprefix']) {
|
||
$name = strtolower(trim((string)\Phpcmf\Service::C()->member_cache['register']['unprefix'])).$name;
|
||
}
|
||
|
||
// 重复账号时
|
||
if ($this->db->table('member')->where('username', $name)->countAllResults()) {
|
||
$name = $this->_register_rand_username($member, $ct + 1);
|
||
}
|
||
|
||
return $name;
|
||
}
|
||
|
||
// 修改账号
|
||
public function edit_username($uid, $username) {
|
||
|
||
$this->clear_cache($uid, $username);
|
||
|
||
$this->table('member')->update($uid, [
|
||
'username' => $username,
|
||
]);
|
||
|
||
$this->db->table('member_group_verify')->where('uid', $uid)->update([ 'username' => $username ]);
|
||
|
||
\Phpcmf\Service::L('cache')->set_data('member-info-'.$uid, '', 1);
|
||
}
|
||
|
||
// 清理指定用户缓存
|
||
public function clear_cache($uid, $username = '') {
|
||
|
||
\Phpcmf\Service::L('cache')->del_data('member-info-'.$uid);
|
||
$username && \Phpcmf\Service::L('cache')->del_data('member-info-name-'.$username);
|
||
}
|
||
|
||
// 按用户uid查询表id集合
|
||
protected function _get_data_ids($uid, $table) {
|
||
|
||
}
|
||
|
||
// 用户系统缓存
|
||
public function cache($site = SITE_ID) {
|
||
|
||
if (!IS_USE_MEMBER) {
|
||
// 获取会员全部配置信息
|
||
$cache = [
|
||
'field' => [],
|
||
'authid' => [ 0 ],
|
||
'group' => [],
|
||
'config' => [],
|
||
'pay' => [],
|
||
];
|
||
if ($this->db->tableExists($this->dbprefix('member_setting'))) {
|
||
$result = $this->db->table('member_setting')->get()->getResultArray();
|
||
if ($result) {
|
||
foreach ($result as $t) {
|
||
$cache[$t['name']] = dr_string2array($t['value']);
|
||
}
|
||
}
|
||
}
|
||
|
||
\Phpcmf\Service::L('cache')->set_file('member', $cache);
|
||
} else {
|
||
\Phpcmf\Service::M('member', 'member')->member_cache();
|
||
}
|
||
}
|
||
|
||
} |