PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/service/user/srv/PwRegisterService.php

https://github.com/cuijinquan/nextwind
PHP | 390 lines | 201 code | 27 blank | 162 comment | 44 complexity | c5ea117a9a503ab3c945048896f20858 MD5 | raw file
  1. <?php
  2. Wind::import('SRV:service.user.validator.PwUserValidator');
  3. Wind::import('LIB:utility.PwMail');
  4. Wind::import('SRV:credit.bo.PwCreditBo');
  5. Wind::import('SRV:user.PwUser');
  6. /**
  7. * 用户注册
  8. *
  9. * @author xiaoxia.xu <xiaoxia.xuxx@aliyun-inc.com>
  10. * @copyright ©2003-2103 phpwind.com
  11. * @license http://www.phpwind.com
  12. * @version $Id: PwRegisterService.php 25182 2013-03-06 07:54:07Z long.shi $
  13. * @package src.service.user.srv
  14. */
  15. class PwRegisterService extends PwBaseHookService {
  16. public $config = null;
  17. private $activeCodeValidTime = 3;//激活码有效期,单位小时
  18. /* @var $userDm PwUserInfoDm */
  19. private $userDm = null;
  20. /* @var $isOpenInvite int 是否开启邀请注册,开启时该值为1 */
  21. public $isOpenInvite = 0;
  22. /* @var $isOpenMobileCheck int 是否开启手机验证,开启时该值为1 */
  23. public $isOpenMobileCheck = 0;
  24. public function __construct() {
  25. parent::__construct();
  26. $this->config = Wekit::C('register');
  27. $this->isOpenInvite = (2 == $this->config['type'] ? 1 : 0);
  28. $this->isOpenMobileCheck = (1 == $this->config['active.phone'] ? 1 : 0);
  29. }
  30. /**
  31. * 检查是否设置同一IP设置一段时间内不能注册
  32. *
  33. * @param string $ip 待检查的IP
  34. * @return true|PwError
  35. */
  36. public function checkIp($ip) {
  37. if (!($ipSpace = abs($this->config['security.ip']))) return true;
  38. $space = $ipSpace * 3600;
  39. /* @var $registerDs PwUserRegisterIp */
  40. $registerDs = Wekit::load('user.PwUserRegisterIp');
  41. $data = $registerDs->getRecodeByIp($ip);
  42. if (!$data || Pw::getTime() - $data['last_regdate'] > $space) return true;
  43. return new PwError('USER:register.error.security.ip', array('{ipSpace}' => $ipSpace));
  44. }
  45. /**
  46. * 设置用户信息
  47. *
  48. * @param PwUserInfoDm $userForm
  49. */
  50. public function setUserDm(PwUserInfoDm $userDm) {
  51. $this->userDm = $this->filterUserDm($userDm);
  52. }
  53. /**
  54. * 返回用户信息的DM
  55. *
  56. * @return PwUserInfoDm
  57. */
  58. public function getUserDm() {
  59. return $this->userDm;
  60. }
  61. /**
  62. * 用户注册信息
  63. *
  64. * @return boolean|int
  65. */
  66. public function register() {
  67. if (!$this->userDm) return new PwError('USER:illegal.request');
  68. if (($result = $this->checkIp($this->userDm->getField('regip'))) instanceof PwError) {
  69. return $result;
  70. }
  71. //[c_register]:调用插件中用户注册操作的前置方法beforeRegister
  72. if (($result = $this->runWithVerified('beforeRegister', $this->userDm)) instanceof PwError) {
  73. return $result;
  74. }
  75. if (($uid = $this->_getUserDs()->addUser($this->userDm)) instanceof PwError) {
  76. return $uid;
  77. }
  78. $this->userDm->setUid($uid);
  79. return $this->afterRegister($this->userDm);
  80. }
  81. /**
  82. * 同步用户数据
  83. *
  84. * 如果本地有用户数据
  85. * 如果本地没有用户数据,则将用户数据从windid同步过来
  86. *
  87. * @param int $uid
  88. * @return array
  89. */
  90. public function sysUser($uid) {
  91. $info = $this->_getUserDs()->getUserByUid($uid, PwUser::FETCH_MAIN);
  92. if (!$info) {
  93. //从windid这边将数据同步到论坛
  94. if (!$this->_getUserDs()->activeUser($uid)) return false;
  95. //更新用户信息
  96. $pwUserInfoDm = new PwUserInfoDm($uid);
  97. $_userinfo = $this->_getUserDs()->getUserByUid($uid, PwUser::FETCH_MAIN | PwUser::FETCH_DATA);
  98. $this->_getUserDs()->editUser($this->filterUserDm($pwUserInfoDm, $_userinfo));
  99. Wekit::load('user.srv.PwUserService')->restoreDefualtAvatar($info['uid']);
  100. $pwUserInfoDm->setUsername($_userinfo['username']);
  101. $pwUserInfoDm->setEmail($_userinfo['email']);
  102. $pwUserInfoDm->setRegip(Wind::getComponent('request')->getClientIp());
  103. $info = $this->afterRegister($pwUserInfoDm);
  104. $this->sendEmailActive($_userinfo['username'], $_userinfo['email']);
  105. }
  106. return $info;
  107. }
  108. /**
  109. * 需要发送新用户激活邮件
  110. *
  111. * @param string $username 用户名
  112. * @param string $email 用户邮件
  113. * @param string $statu 激活标志
  114. * @param int $uid 用户ID
  115. * @return boolean
  116. */
  117. public function sendEmailActive($username, $email, $statu = '', $uid = 0) {
  118. if (!$this->config['active.mail']) return true;
  119. if ($uid == 0 || !$statu) {
  120. $info = $this->_getUserDs()->getUserByName($username, PwUser::FETCH_MAIN);
  121. if ($info['email'] != $email) return new PwError('USER:illegal.request');
  122. $uid = $info['uid'];
  123. $statu = self::createRegistIdentify($uid, $info['password']);
  124. }
  125. if (!Wind::getComponent('router')->getRoute('pw')) {
  126. Wind::getComponent('router')->addRoute('pw', WindFactory::createInstance(Wind::import('LIB:route.PwRoute'), array('bbs')));
  127. }
  128. $code = substr(md5(Pw::getTime()), mt_rand(1, 8), 8);
  129. $url = WindUrlHelper::createUrl('u/register/activeEmail', array('code' => $code, '_statu' => $statu), '', 'pw');
  130. list($title, $content) = $this->_buildTitleAndContent('active.mail.title', 'active.mail.content', $username, $url);
  131. /* @var $activeCodeDs PwUserActiveCode */
  132. $activeCodeDs = Wekit::load('user.PwUserActiveCode');
  133. $activeCodeDs->addActiveCode($uid, $email, $code, Pw::getTime());
  134. $mail = new PwMail();
  135. $mail->sendMail($email, $title, $content);
  136. return true;
  137. }
  138. /**
  139. * 检查是否已经发送了激活邮箱
  140. *
  141. * @param int $uid 用户ID
  142. * @param string $email 用户邮箱
  143. * @return boolean
  144. */
  145. public function checkIfActiveEmailSend($uid, $email) {
  146. /* @var $activeCodeDs PwUserActiveCode */
  147. $activeCodeDs = Wekit::load('user.PwUserActiveCode');
  148. $info = $activeCodeDs->getInfoByUid($uid);
  149. if (!$info || $info['email'] != $email || $info['active_time'] > 0) return false;
  150. $validTime = $this->activeCodeValidTime * 3600;
  151. //过期了
  152. if (($info['send_time'] + $validTime) < Pw::getTime()) return false;
  153. return true;
  154. }
  155. /**
  156. * 激活email
  157. *
  158. * @param int $uid 用户ID
  159. * @param string $email 用户Email
  160. * @param string $code 激活码
  161. * @return boolean
  162. */
  163. public function activeEmail($uid, $email, $code) {
  164. /* @var $activeCodeDs PwUserActiveCode */
  165. $activeCodeDs = Wekit::load('user.PwUserActiveCode');
  166. $info = $activeCodeDs->getInfoByUid($uid);
  167. if (!$info || $info['email'] != $email || $info['code'] != $code) return new PwError("USER:illegal.request");
  168. if ($info['active_time'] > 0 ) return new PwError('USER:active.email.dumplicate');
  169. $validTime = $this->activeCodeValidTime * 3600;
  170. if (($info['send_time'] + $validTime) < Pw::getTime()) return new PwError('USER:active.email.overtime');
  171. $activeCodeDs->activeCode($uid, Pw::getTime());
  172. $info = $this->_getUserDs()->getUserByUid($uid, PwUser::FETCH_MAIN);
  173. if (Pw::getstatus($info['status'], PwUser::STATUS_UNACTIVE)) {
  174. $userDm = new PwUserInfoDm($info['uid']);
  175. $userDm->setUnactive(false);
  176. (!Pw::getstatus($info['status'], PwUser::STATUS_UNCHECK)) && $userDm->setGroupid(0);
  177. $this->_getUserDs()->editUser($userDm, PwUser::FETCH_MAIN);
  178. }
  179. /* @var $registerCheckDs PwUserRegisterCheck */
  180. $registerCheckDs = Wekit::load('user.PwUserRegisterCheck');
  181. $registerCheckDs->activeUser($uid);
  182. return true;
  183. }
  184. /**
  185. * 发送欢迎信息
  186. *
  187. * @param int $uid 用户ID
  188. * @param string $username 用户名
  189. * @param string $email 邮箱
  190. * @return boolean
  191. */
  192. public function sendWelcomeMsg($uid, $username, $email) {
  193. list($title, $content) = $this->_buildTitleAndContent('welcome.title', 'welcome.content', $username);
  194. if (in_array(1, $this->config['welcome.type'])) {
  195. /* @var $notice PwNoticeService */
  196. $notice = Wekit::load('message.srv.PwNoticeService');
  197. $notice->sendDefaultNotice($uid, $content, $title);
  198. }
  199. /*如果含有激活邮件则发送到*/
  200. if (!in_array(2, $this->config['welcome.type'])) return true;
  201. //如果是邮件激活开启,则不需要发送欢迎邮件
  202. if ($this->config['active.mail'] == 1) return true;
  203. $mail = new PwMail();
  204. $mail->sendMail($email, $title, $content);
  205. return true;
  206. }
  207. /**
  208. * 构造用户标志
  209. *
  210. * @param int $uid 用户ID
  211. * @param string $pwd 用户密码
  212. * @return string
  213. */
  214. public static function createRegistIdentify($uid, $pwd) {
  215. $code = Pw::encrypt($uid . "\t" . Pw::getPwdCode($pwd));
  216. return rawurlencode($code);
  217. }
  218. /**
  219. * 检查用户标志
  220. *
  221. * @param string $identify
  222. * @return array array($uid, $password);
  223. */
  224. public static function parserRegistIdentify($identify) {
  225. return explode("\t", Pw::decrypt(rawurldecode($identify)));
  226. }
  227. /**
  228. * 完成注册的后期执行
  229. *
  230. * @param PwUserInfoDm $userDm
  231. * @return array
  232. */
  233. protected function afterRegister(PwUserInfoDm $userDm) {
  234. //Wekit::load('user.srv.PwUserService')->restoreDefualtAvatar($uid); windid处理
  235. //获得注册积分
  236. /* @var $creditBo PwCreditBo */
  237. $creditBo = PwCreditBo::getInstance();
  238. $creditBo->operate('register', new PwUserBo($userDm->uid));
  239. $this->updateRegisterIp($userDm->getField('regip'), Pw::getTime());
  240. $this->updateRegisterCheck($userDm->uid);
  241. $this->sendWelcomeMsg($userDm->uid, $userDm->getField('username'), $userDm->getField('email'));
  242. //[c_register]:调用插件中用户注册操作的后置方法afterRegister
  243. if (($result = $this->runWithVerified('afterRegister', $userDm)) instanceof PwError) return $result;
  244. return $this->_getUserDs()->getUserByUid($userDm->uid, PwUser::FETCH_MAIN);
  245. }
  246. /**
  247. * 过滤用户DM同时设置用户的相关信息
  248. *
  249. * @param PwUserInfoDm $userDm
  250. * @param array $hasCredit
  251. * @return PwUserInfoDm
  252. */
  253. protected function filterUserDm(PwUserInfoDm $userDm, $hasCredit = array()) {
  254. //如果开启邮箱激活,则设置该状态为0,否则设置该状态为1
  255. $_uncheckGid = false;
  256. if ($this->config['active.mail']) {
  257. $userDm->setUnactive(true);
  258. $_uncheckGid = true;
  259. }
  260. //如果开启审核,则设置该状态为0,否则设置该状态为1
  261. if ($this->config['active.check']) {
  262. $userDm->setUncheck(true);
  263. $_uncheckGid = true;
  264. }
  265. //【用户注册】未验证用户组
  266. if ($_uncheckGid) {
  267. $userDm->setGroupid(7);
  268. $userDm->setGroups(array());
  269. }
  270. $_credit = $this->_getRegisterAddCredit($hasCredit);
  271. //【用户注册】计算memberid
  272. /* @var $groupService PwUserGroupsService */
  273. $groupService = Wekit::load('usergroup.srv.PwUserGroupsService');
  274. $credit = $groupService->calculateCredit(Wekit::C('site', 'upgradestrategy'), $_credit);
  275. $memberid = $groupService->calculateLevel($credit);
  276. $userDm->setMemberid($memberid);
  277. return $userDm;
  278. }
  279. /**
  280. * 获取注册可以添加的积分
  281. *
  282. * @param array $_credit 已有的积分
  283. * @return array
  284. */
  285. private function _getRegisterAddCredit($_credit = array()) {
  286. //【用户注册】注册成功初始积分---积分策略中获取
  287. /* @var $creditBo PwCreditBo */
  288. $creditBo = PwCreditBo::getInstance();
  289. $creditStrategy = $creditBo->getStrategy('register');
  290. !$creditStrategy['credit'] && $creditStrategy['credit'] = array();
  291. foreach ($creditStrategy['credit'] as $id => $_v) {
  292. $_id = 'credit' . $id;
  293. if (isset($_credit[$_id])) {
  294. $_credit[$_id] += $_v;
  295. } else {
  296. $_credit[$_id] = $_v;
  297. }
  298. }
  299. return $_credit;
  300. }
  301. /**
  302. * 获得信息的标题和内容
  303. *
  304. * @param string $titleKey 标题key
  305. * @param string $contentKey 内容key
  306. * @param string $username 用户名
  307. * @param string $url 链接地址
  308. * @return array
  309. */
  310. private function _buildTitleAndContent($titleKey, $contentKey, $username, $url = '') {
  311. $search = array('{username}', '{sitename}');
  312. $replace = array($username, Wekit::C('site', 'info.name'));
  313. $title = str_replace($search, $replace, $this->config[$titleKey]);
  314. $search[] = '{time}';
  315. $search[] = '{url}';
  316. $replace[] = Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s');
  317. $replace[] = $url ? sprintf('<a href="%s">%s</a>', $url, $url) : '';
  318. $content = str_replace($search, $replace, $this->config[$contentKey]);
  319. return array($title, $content);
  320. }
  321. /**
  322. * 更新注册IP
  323. *
  324. * @param string $ip 注册的IP
  325. * @param int $time 注册时间
  326. * @return boolean
  327. */
  328. private function updateRegisterIp($ip, $time) {
  329. if (!$this->config['security.ip']) return true;
  330. /* @var $registerDa PwUserRegisterIp */
  331. $registerDs = Wekit::load('user.PwUserRegisterIp');
  332. return $registerDs->updateRecodeByIp($ip, $time);
  333. }
  334. /**
  335. * 更新用户注册相关的审核/激活表
  336. *
  337. * @param int $uid
  338. * @return boolean
  339. */
  340. private function updateRegisterCheck($uid) {
  341. //添加到注册审核表中
  342. $_ifactive = $this->config['active.mail'] ? 0 : 1;
  343. $_ifcheck = $this->config['active.check'] ? 0 : 1;
  344. /* @var $registerCheckDs PwUserRegisterCheck */
  345. $registerCheckDs = Wekit::load('user.PwUserRegisterCheck');
  346. $registerCheckDs->addInfo($uid, $_ifcheck, $_ifactive);
  347. return true;
  348. }
  349. /**
  350. * 获得用户DS
  351. *
  352. * @return PwUser
  353. */
  354. private function _getUserDs() {
  355. return Wekit::load('user.PwUser');
  356. }
  357. /* (non-PHPdoc)
  358. * @see PwBaseHookService::_getInterfaceName()
  359. */
  360. protected function _getInterfaceName() {
  361. return 'PwRegisterDoBase';
  362. }
  363. }