国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

563 rindas
19KB

  1. <?php
  2. if (!defined('DEDEINC')) exit ('dedebiz');
  3. /**
  4. * 会员登录
  5. *
  6. * @version $id:userlogin.class.php 15:59 2010年7月5日 tianya $
  7. * @package DedeBIZ.Libraries
  8. * @copyright Copyright (c) 2022 DedeBIZ.COM
  9. * @license GNU GPL v2 (https://www.dedebiz.com/license)
  10. * @link https://www.dedebiz.com
  11. */
  12. helper('cache');
  13. /**
  14. * 检查账号的合法性
  15. *
  16. * @access public
  17. * @param string $uid 会员UID
  18. * @param string $msgtitle 提示标题
  19. * @param string $ckhas 检查是否存在
  20. * @return string
  21. */
  22. function CheckUserID($uid, $msgtitle = '账号', $ckhas = TRUE)
  23. {
  24. global $cfg_mb_notallow, $cfg_mb_idmin, $cfg_md_idurl, $cfg_soft_lang, $dsql;
  25. if ($cfg_mb_notallow != '') {
  26. $nas = explode(',', $cfg_mb_notallow);
  27. if (in_array($uid, $nas)) {
  28. return $msgtitle.'系统禁止的标识';
  29. }
  30. }
  31. if ($cfg_md_idurl == 'Y' && preg_match("/[^a-z0-9]/i", $uid)) {
  32. return $msgtitle.'必须由英文字母和数字组合';
  33. }
  34. if ($cfg_soft_lang == 'utf-8') {
  35. $ck_uid = utf82gb($uid);
  36. } else {
  37. $ck_uid = $uid;
  38. }
  39. for ($i = 0; isset($ck_uid[$i]); $i++) {
  40. if (ord($ck_uid[$i]) > 0x80) {
  41. if (isset($ck_uid[$i + 1]) && ord($ck_uid[$i + 1]) > 0x40) {
  42. $i++;
  43. } else {
  44. return $msgtitle.'建议用英文字母和数字组合';
  45. }
  46. } else {
  47. if (preg_match("/[^0-9a-z@\.-]/i", $ck_uid[$i])) {
  48. return $msgtitle.'请使用数字0-9小写a-z大写A-Z符号_@!.-';
  49. }
  50. }
  51. }
  52. if ($ckhas) {
  53. $row = $dsql->GetOne("SELECT * FROM `#@__member` WHERE userid LIKE '$uid' ");
  54. if (is_array($row)) return $msgtitle."已存在";
  55. }
  56. return 'ok';
  57. }
  58. /**
  59. * 检查会员是否被禁言
  60. *
  61. * @return void
  62. */
  63. function CheckNotAllow()
  64. {
  65. global $cfg_ml;
  66. if (empty($cfg_ml->M_ID)) return;
  67. if ($cfg_ml->M_Spacesta == -2) {
  68. ShowMsg("您已经被禁言,请与管理员联系", "-1");
  69. exit();
  70. } else if ($cfg_ml->M_Spacesta == -10) {
  71. ShowMsg("系统开启了邮件审核机制,帐号需要审核后才能发信息", "-1");
  72. exit();
  73. } else if ($cfg_ml->M_Spacesta < 0) {
  74. ShowMsg('系统开启了审核机制,帐号需要管理员审核后才能发信息', '-1');
  75. exit();
  76. }
  77. }
  78. function FormatUsername($username)
  79. {
  80. $username = str_replace("`", "‘", $username);
  81. $username = str_replace("'", "‘", $username);
  82. $username = str_replace("\"", "“", $username);
  83. $username = str_replace(",", ",", $username);
  84. $username = str_replace("(", "(", $username);
  85. $username = str_replace(")", ")", $username);
  86. return addslashes($username);
  87. }
  88. /**
  89. * 网站会员登录类
  90. *
  91. * @package MemberLogin
  92. * @subpackage DedeBIZ.Libraries
  93. * @link https://www.dedebiz.com
  94. */
  95. class MemberLogin
  96. {
  97. var $M_ID;
  98. var $M_LoginID;
  99. var $M_MbType;
  100. var $M_Money;
  101. var $M_UserMoney;
  102. var $M_Scores;
  103. var $M_UserName;
  104. var $M_Rank;
  105. var $M_Face;
  106. var $M_LoginTime;
  107. var $M_KeepTime;
  108. var $M_Spacesta;
  109. var $fields;
  110. var $M_UpTime;
  111. var $M_ExpTime;
  112. var $M_HasDay;
  113. var $M_JoinTime;
  114. var $M_Honor = '';
  115. var $M_SendMax = 1;//默认游客投稿数
  116. var $memberCache = 'memberlogin';
  117. var $dsql;
  118. //php5构造函数
  119. function __construct($kptime = -1, $cache = FALSE)
  120. {
  121. global $dsql;
  122. $this->dsql = $dsql;
  123. if ($kptime == -1) {
  124. $this->M_KeepTime = 3600 * 24 * 7;
  125. } else {
  126. $this->M_KeepTime = $kptime;
  127. }
  128. $formcache = FALSE;
  129. $this->M_ID = $this->GetNum(GetCookie("DedeUserID"));
  130. $this->M_LoginTime = GetCookie("DedeLoginTime");
  131. $this->fields = array();
  132. if (empty($this->M_ID)) {
  133. $this->ResetUser();
  134. } else {
  135. $this->M_ID = intval($this->M_ID);
  136. if ($cache) {
  137. $this->fields = GetCache($this->memberCache, $this->M_ID);
  138. if (empty($this->fields)) {
  139. $this->fields = $this->dsql->GetOne("SELECT * FROM `#@__member` WHERE mid='{$this->M_ID}' ");
  140. } else {
  141. $formcache = TRUE;
  142. }
  143. } else {
  144. $this->fields = $this->dsql->GetOne("SELECT * FROM `#@__member` WHERE mid='{$this->M_ID}' ");
  145. }
  146. if (is_array($this->fields)) {
  147. //间隔一小时更新一次会员登录时间
  148. if (time() - $this->M_LoginTime > 3600) {
  149. $this->dsql->ExecuteNoneQuery("update `#@__member` set logintime='".time()."',loginip='".GetIP()."' WHERE mid='".$this->fields['mid']."';");
  150. PutCookie("DedeLoginTime", time(), $this->M_KeepTime);
  151. }
  152. $this->M_LoginID = $this->fields['userid'];
  153. $this->M_MbType = $this->fields['mtype'];
  154. $this->M_Money = $this->fields['money'];
  155. $this->M_UserMoney = $this->fields['user_money'];
  156. $this->M_UserName = FormatUsername($this->fields['uname']);
  157. $this->M_Scores = $this->fields['scores'];
  158. $this->M_Face = $this->fields['face'];
  159. $this->M_Rank = $this->fields['rank'];
  160. $this->M_Spacesta = $this->fields['spacesta'];
  161. $sql = "SELECT titles From `#@__scores` WHERE integral<={$this->fields['scores']} ORDER BY integral DESC";
  162. $scrow = $this->dsql->GetOne($sql);
  163. $this->fields['honor'] = $scrow['titles'];
  164. $this->M_Honor = $this->fields['honor'];
  165. $this->M_UpTime = $this->fields['uptime'];
  166. $this->M_ExpTime = $this->fields['exptime'];
  167. $this->M_SendMax = $this->fields['send_max'];
  168. $this->M_JoinTime = MyDate('Y-m-d', $this->fields['jointime']);
  169. if ($this->M_Rank > 10 && $this->M_UpTime > 0) {
  170. $this->M_HasDay = $this->Judgemember();
  171. }
  172. if (!$formcache) {
  173. SetCache($this->memberCache, $this->M_ID, $this->fields, 1800);
  174. }
  175. } else {
  176. $this->ResetUser();
  177. }
  178. }
  179. }
  180. function MemberLogin($kptime = -1)
  181. {
  182. $this->__construct($kptime);
  183. }
  184. /**
  185. * 删除缓存,每次登录时和在修改会员资料的地方会清除
  186. *
  187. * @access public
  188. * @param string
  189. * @return string
  190. */
  191. function DelCache($mid)
  192. {
  193. DelCache($this->memberCache, $mid);
  194. }
  195. /**
  196. * 判断会员是否到期
  197. *
  198. * @return string
  199. */
  200. function Judgemember()
  201. {
  202. global $cfg_mb_rank;
  203. $nowtime = time();
  204. $mhasDay = $this->M_ExpTime - ceil(($nowtime - $this->M_UpTime) / 3600 / 24) + 1;
  205. if ($mhasDay <= 0) {
  206. $this->dsql->ExecuteNoneQuery("UPDATE `#@__member` SET uptime='0',exptime='0',`rank`='$cfg_mb_rank' WHERE mid='".$this->fields['mid']."';");
  207. }
  208. return $mhasDay;
  209. }
  210. /**
  211. * 退出cookie的会话
  212. *
  213. * @return void
  214. */
  215. function ExitCookie()
  216. {
  217. $this->ResetUser();
  218. }
  219. /**
  220. * 验证会员是否已经登录
  221. *
  222. * @return bool
  223. */
  224. function IsLogin()
  225. {
  226. if ($this->M_ID > 0) return TRUE;
  227. else return FALSE;
  228. }
  229. /**
  230. * 检测会员上传空间
  231. *
  232. * @return int
  233. */
  234. function GetUserSpace()
  235. {
  236. $uid = $this->M_ID;
  237. $row = $this->dsql->GetOne("SELECT sum(filesize) AS fs FROM `#@__uploads` WHERE mid='$uid';");
  238. return intval($row['fs']);
  239. }
  240. /**
  241. * 检查会员空间是否已满
  242. *
  243. * @return bool
  244. */
  245. function CheckUserSpaceIsFull()
  246. {
  247. global $cfg_mb_max;
  248. if ($cfg_mb_max == 0) {
  249. return false;
  250. }
  251. $hasuse = $this->GetUserSpace();
  252. $maxSize = $cfg_mb_max * 1024 * 1024;
  253. if ($hasuse >= $maxSize) {
  254. return true;
  255. }
  256. return false;
  257. }
  258. /**
  259. * 更新会员信息统计表
  260. *
  261. * @access public
  262. * @param string $field 字段信息
  263. * @param string $uptype 更新类型
  264. * @return string
  265. */
  266. function UpdateUserTj($field, $uptype = 'add')
  267. {
  268. $mid = $this->M_ID;
  269. $arr = $this->dsql->GetOne("SELECT * `#@__member_tj` WHERE mid='$mid' ");
  270. if (!is_array($arr)) {
  271. $arr = array('article' => 0, 'album' => 0, 'archives' => 0, 'homecount' => 0, 'pagecount' => 0, 'feedback' => 0, 'friend' => 0, 'stow' => 0);
  272. }
  273. extract($arr);
  274. if (isset($$field)) {
  275. if ($uptype == 'add') {
  276. $$field++;
  277. } else if ($$field > 0) {
  278. $$field--;
  279. }
  280. }
  281. $inquery = "INSERT INTO `#@__member_tj` (`mid`,`article`,`album`,`archives`,`homecount`,`pagecount`,`feedback`,`friend`,`stow`) VALUES ('$mid','$article','$album','$archives','$homecount','$pagecount','$feedback','$friend','$stow'); ";
  282. $this->dsql->ExecuteNoneQuery("DELETE FROM `#@__member_tj` WHERE mid='$mid' ");
  283. $this->dsql->ExecuteNoneQuery($inquery);
  284. }
  285. /**
  286. * 重置会员信息
  287. *
  288. * @return void
  289. */
  290. function ResetUser()
  291. {
  292. $this->fields = '';
  293. $this->M_ID = 0;
  294. $this->M_LoginID = '';
  295. $this->M_Rank = 0;
  296. $this->M_Face = '';
  297. $this->M_Money = 0;
  298. $this->M_UserMoney = 0;
  299. $this->M_UserName = '';
  300. $this->M_LoginTime = 0;
  301. $this->M_MbType = '';
  302. $this->M_Scores = 0;
  303. $this->M_Spacesta = -2;
  304. $this->M_UpTime = 0;
  305. $this->M_ExpTime = 0;
  306. $this->M_JoinTime = 0;
  307. $this->M_HasDay = 0;
  308. DropCookie('DedeUserID');
  309. DropCookie('DedeLoginTime');
  310. }
  311. /**
  312. * 获取整数值
  313. *
  314. * @access public
  315. * @param string $fnum 处理的数值
  316. * @return string
  317. */
  318. function GetNum($fnum)
  319. {
  320. $fnum = preg_replace("/[^0-9\.]/", '', $fnum);
  321. return $fnum;
  322. }
  323. /**
  324. * 会员登录,把登录密码转为指定长度md5数据
  325. *
  326. * @access public
  327. * @param string $pwd 需要加密的密码
  328. * @return string
  329. */
  330. function GetEncodePwd($pwd)
  331. {
  332. global $cfg_mb_pwdtype;
  333. if (empty($cfg_mb_pwdtype)) $cfg_mb_pwdtype = '32';
  334. switch ($cfg_mb_pwdtype) {
  335. case 'l16':
  336. return substr(md5($pwd), 0, 16);
  337. case 'r16':
  338. return substr(md5($pwd), 16, 16);
  339. case 'm16':
  340. return substr(md5($pwd), 8, 16);
  341. default:
  342. return md5($pwd);
  343. }
  344. }
  345. /**
  346. * 会员登录,把数据库密码转为特定长度,如果数据库密码是明文,本程序不支持
  347. *
  348. * @access public
  349. * @param string
  350. * @return string
  351. */
  352. function GetShortPwd($dbpwd)
  353. {
  354. global $cfg_mb_pwdtype;
  355. if (empty($cfg_mb_pwdtype)) $cfg_mb_pwdtype = '32';
  356. $dbpwd = trim($dbpwd);
  357. if (strlen($dbpwd) == 16) {
  358. return $dbpwd;
  359. } else {
  360. switch ($cfg_mb_pwdtype) {
  361. case 'l16':
  362. return substr($dbpwd, 0, 16);
  363. case 'r16':
  364. return substr($dbpwd, 16, 16);
  365. case 'm16':
  366. return substr($dbpwd, 8, 16);
  367. default:
  368. return $dbpwd;
  369. }
  370. }
  371. }
  372. /**
  373. * 投稿是否被限制
  374. *
  375. * @return array
  376. */
  377. function IsSendLimited()
  378. {
  379. $ttime = strtotime("today");
  380. $arr = $this->dsql->GetOne("SELECT COUNT(*) as dd FROM `#@__arctiny` WHERE mid='{$this->M_ID}' AND senddate >= $ttime");
  381. if (is_array($arr)) {
  382. if ($this->M_SendMax < 0) {
  383. return false;
  384. }
  385. if ($arr['dd'] >= $this->M_SendMax) {
  386. return true;
  387. } else {
  388. return false;
  389. }
  390. } else {
  391. return true;
  392. }
  393. }
  394. /**
  395. * 检查会员是否合法
  396. *
  397. * @access public
  398. * @param string $loginuser 登录账号
  399. * @param string $loginpwd 密码
  400. * @return string
  401. */
  402. function CheckUser(&$loginuser, $loginpwd)
  403. {
  404. //检测账号的合法性
  405. $rs = CheckUserID($loginuser, '账号', FALSE);
  406. //账号不正确时返回验证错误,原登录名通过引用返回错误提示信息
  407. if ($rs != 'ok') {
  408. $loginuser = $rs;
  409. return '0';
  410. }
  411. //matt=10是管理员关连的前台帐号,为了安全起见,这个帐号只能从后台登录,不能直接从前台登录
  412. $row = $this->dsql->GetOne("SELECT mid,matt,pwd,pwd_new,logintime FROM `#@__member` WHERE userid LIKE '$loginuser' ");
  413. if (is_array($row)) {
  414. if (!empty($row['pwd_new']) && !password_verify($loginpwd, $row['pwd_new'])) {
  415. $this->loginError($loginuser);
  416. return -1;
  417. } else if (!empty($row['pwd']) && $this->GetShortPwd($row['pwd']) != $this->GetEncodePwd($loginpwd)) {
  418. $this->loginError($loginuser);
  419. return -1;
  420. } else {
  421. if (empty($row['pwd_new']) && function_exists('password_hash')) {
  422. //升级密码
  423. $newpwd = password_hash($loginpwd, PASSWORD_BCRYPT);
  424. $inquery = "UPDATE `#@__member` SET pwd='',pwd_new='{$newpwd}' WHERE mid='".$row['mid']."'";
  425. $this->dsql->ExecuteNoneQuery($inquery);
  426. }
  427. //管理员帐号不允许从前台登录
  428. if ($row['matt'] == 10) {
  429. return -2;
  430. } else {
  431. $this->PutLoginInfo($row['mid'], $row['logintime']);
  432. return 1;
  433. }
  434. }
  435. } else {
  436. return 0;
  437. }
  438. }
  439. /**
  440. * 是否需要验证码
  441. *
  442. * @param mixed $loginuser
  443. * @return bool
  444. */
  445. function isNeedCheckCode($loginuser)
  446. {
  447. $num = $this->getLoginError($loginuser);
  448. return $num >= 3 ? true : false;
  449. }
  450. /**
  451. * 1分钟以内登录错误的次数
  452. *
  453. * @param mixed $loginuser
  454. * @return int 登录错误次数
  455. */
  456. function getLoginError($loginuser)
  457. {
  458. $rs = CheckUserID($loginuser, '账号', FALSE);
  459. //账号不正确时返回验证错误,原登录名通过引用返回错误提示信息
  460. if ($rs != 'ok') {
  461. return -1;
  462. }
  463. if (!TableHasField("#@__member", "loginerr")) {
  464. return 0;
  465. }
  466. $row = $this->dsql->GetOne("SELECT loginerr,logintime FROM `#@__member` WHERE userid LIKE '$loginuser'");
  467. if (is_array($row)) {
  468. //1分钟内如果输错3次则需要验证码
  469. return (time() - (int)$row['logintime']) < 60 ? (int)$row['loginerr'] : 0;
  470. } else {
  471. return -1;
  472. }
  473. }
  474. /**
  475. * 记录登录错误
  476. *
  477. * @return void
  478. */
  479. function loginError($loginuser)
  480. {
  481. $rs = CheckUserID($loginuser, '账号', FALSE);
  482. //账号不正确时返回验证错误,原登录名通过引用返回错误提示信息
  483. if ($rs != 'ok') {
  484. return;
  485. }
  486. $loginip = GetIP();
  487. $inquery = "UPDATE `#@__member` SET loginip='$loginip',logintime='".time()."',loginerr=loginerr+1 WHERE userid='".$loginuser."'";
  488. $this->dsql->ExecuteNoneQuery($inquery);
  489. }
  490. /**
  491. * 保存会员cookie
  492. *
  493. * @access public
  494. * @param string $uid 会员id
  495. * @param string $logintime 登录限制时间
  496. * @return void
  497. */
  498. function PutLoginInfo($uid, $logintime = 0)
  499. {
  500. global $cfg_login_adds;
  501. //登录添加积分,上一次登录时间必须大于两小时
  502. if (time() - $logintime > 7200 && $cfg_login_adds > 0) {
  503. $this->dsql->ExecuteNoneQuery("UPDATE `#@__member` SET `scores`=`scores`+{$cfg_login_adds} WHERE mid='$uid' ");
  504. }
  505. $this->M_ID = $uid;
  506. $this->M_LoginTime = time();
  507. $loginip = GetIP();
  508. $inquery = "UPDATE `#@__member` SET loginip='$loginip',logintime='".$this->M_LoginTime."',loginerr=0 WHERE mid='".$uid."'";
  509. $this->dsql->ExecuteNoneQuery($inquery);
  510. if ($this->M_KeepTime > 0) {
  511. PutCookie('DedeUserID', $uid, $this->M_KeepTime);
  512. PutCookie('DedeLoginTime', $this->M_LoginTime, $this->M_KeepTime);
  513. } else {
  514. PutCookie('DedeUserID', $uid);
  515. PutCookie('DedeLoginTime', $this->M_LoginTime);
  516. }
  517. }
  518. function GetMemberTypeName()
  519. {
  520. if ($this->M_Rank == 0) {
  521. return '注册会员';
  522. } else {
  523. $row = $this->dsql->GetOne("SELECT membername FROM `#@__arcrank` WHERE `rank`='".$this->M_Rank."'");
  524. return $row['membername'];
  525. }
  526. }
  527. /**
  528. * 获得会员目前的状态
  529. *
  530. * @access public
  531. * @return string
  532. */
  533. function GetSta()
  534. {
  535. $sta = '';
  536. if ($this->M_Rank == 0) {
  537. $sta .= "您目前等级是:注册会员";
  538. } else {
  539. $row = $this->dsql->GetOne("SELECT membername FROM `#@__arcrank` WHERE `rank`='".$this->M_Rank."'");
  540. $sta .= "您目前等级是:".$row['membername'];
  541. $rs = $this->dsql->GetOne("SELECT id FROM `#@__admin` WHERE userid='".$this->M_LoginID."'");
  542. if (!is_array($rs)) {
  543. if ($this->M_Rank > 10 && $this->M_HasDay > 0) $sta .= ",剩余".$this->M_HasDay."天";
  544. elseif ($this->M_Rank > 10) $sta .= ",<span class='text-danger'>会员已到期</span>";
  545. }
  546. }
  547. $sta .= ",积分{$this->M_Scores}分,金币{$this->M_Money}个,余额{$this->M_UserMoney}元";
  548. return $sta;
  549. }
  550. //获取能够发布文档的栏目
  551. public static function GetEnabledChannels() {
  552. global $dsql;
  553. $result = array();
  554. $dsql->SetQuery("SELECT channeltype FROM `#@__arctype` GROUP BY channeltype");
  555. $dsql->Execute();
  556. $candoChannel = '';
  557. while ($row = $dsql->GetObject()) {
  558. $result[] = $row->channeltype;
  559. }
  560. return $result;
  561. }
  562. }
  563. ?>