user.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <?php
  2. require_once "../config.php";
  3. require_once "../db/table.php";
  4. require_once "../db/channel.php";
  5. require_once "../public/function.php";
  6. // Require Composer's autoloader.
  7. require_once '../../vendor/autoload.php';
  8. // Using Medoo namespace.
  9. use Medoo\Medoo;
  10. // Require Composer's autoloader.
  11. use PHPMailer\PHPMailer\PHPMailer;
  12. use PHPMailer\PHPMailer\SMTP;
  13. use PHPMailer\PHPMailer\Exception;
  14. /*
  15. CREATE TABLE users (
  16. id INTEGER PRIMARY KEY AUTOINCREMENT,
  17. like_type VARCHAR (16) NOT NULL,
  18. resource_type VARCHAR (32) NOT NULL,
  19. resource_id CHAR (36) NOT NULL,
  20. user_id INTEGER NOT NULL,
  21. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL //只做初始化,更新时不自动更新
  22. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL //自动更新
  23. );
  24. */
  25. class User extends Table
  26. {
  27. function __construct($redis=false) {
  28. parent::__construct(_FILE_DB_USERINFO_, "user", "", "",$redis);
  29. }
  30. public function index(){
  31. $where["like_type"] = "like";
  32. $where["resource_type"] = $_GET["type"];
  33. $where["resource_id"] = explode($_GET["id"],",");
  34. echo json_encode($this->_index(["resource_id","user_id"],$where), JSON_UNESCAPED_UNICODE);
  35. }
  36. public function list(){
  37. if(!isset($_COOKIE["userid"])){
  38. $userId = $_COOKIE["userid"];
  39. }
  40. $json = file_get_contents('php://input');
  41. $data = json_decode($json,true);
  42. foreach ($data as $key => $value) {
  43. # code...
  44. $data[$key]['like']=$this->medoo->count($this->table,[
  45. 'like_type'=>$value['like_type'],
  46. 'resource_type'=>$value['resource_type'],
  47. 'resource_id'=>$value['resource_id'],
  48. ]);
  49. }
  50. if(isset($_COOKIE["userid"])){
  51. $userId = $_COOKIE["userid"];
  52. foreach ($data as $key => $value) {
  53. # code...
  54. $data[$key]['me']=$this->medoo->count($this->table,[
  55. 'like_type'=>$value['like_type'],
  56. 'resource_type'=>$value['resource_type'],
  57. 'resource_id'=>$value['resource_id'],
  58. 'user_id'=>$userId,
  59. ]);
  60. }
  61. }
  62. $this->result["ok"]=true;
  63. $this->result["message"]="";
  64. $this->result["data"]=$data;
  65. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  66. }
  67. public function create(){
  68. $json = file_get_contents('php://input');
  69. $data = json_decode($json,true);
  70. //验证邀请码
  71. if(isset($data["invite"])){
  72. if ($this->redis == false) {
  73. $this->result["ok"]=false;
  74. $this->result["message"]="no_redis_connect";
  75. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  76. return;
  77. }
  78. $redisKey = "invitecode://".$data["invite"];
  79. $code = $this->redis->exists($redisKey);
  80. if(!$code){
  81. $this->result["ok"]=false;
  82. $this->result["message"]="invite_code_invalid";
  83. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  84. return;
  85. }
  86. $data["email"] = $this->redis->get($redisKey);
  87. }else{
  88. $this->result["ok"]=false;
  89. $this->result["message"]="no_invite_code";
  90. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  91. return;
  92. }
  93. //验证用户名有效性
  94. if(!$this->isValidUsername($data["username"])){
  95. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  96. return;
  97. }
  98. //验证昵称有效性
  99. if(!$this->isValidNickName($data["nickname"])){
  100. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  101. return;
  102. }
  103. $isExist = $this->medoo->has($this->table,["username"=>$data["username"]]);
  104. if(!$isExist){
  105. if(!$this->isValidEmail($data["email"])){
  106. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  107. return;
  108. }
  109. $isExist = $this->medoo->has($this->table,["email"=>$data["email"]]);
  110. if(!$isExist){
  111. if(!$this->isValidPassword($data["password"])){
  112. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  113. return;
  114. }
  115. $data["userid"] = UUID::v4();
  116. $data["password"] = md5($data["password"]);
  117. $data["create_time"] = mTime();
  118. $data["modify_time"] = mTime();
  119. $data["setting"] = "{}";
  120. $result = $this->_create($data,["userid","username","email","password","nickname","setting","create_time","modify_time"]);
  121. if($result["ok"]){
  122. $newUserId = $this->medoo->get(
  123. $this->table,
  124. 'id',
  125. ["userid"=>$data['userid']]
  126. );
  127. $channel = new Channel($this->redis);
  128. $newChannel1 = $channel->create([
  129. "owner_uid"=>$data["userid"],
  130. "editor_id"=>$newUserId,
  131. "lang"=>$data["lang"],
  132. "name"=>$data["username"],
  133. "lang"=>$data["lang"],
  134. "status"=>30,
  135. "summary"=>""
  136. ]);
  137. $newChannel2 = $channel->create([
  138. "owner_uid"=>$data["userid"],
  139. "editor_id"=>$newUserId,
  140. "lang"=>$data["lang"],
  141. "name"=>"draft",
  142. "lang"=>$data["lang"],
  143. "status"=>10,
  144. "summary"=>""
  145. ]);
  146. echo json_encode($newChannel1, JSON_UNESCAPED_UNICODE);
  147. //删除
  148. $this->redis->del($redisKey);
  149. }else{
  150. echo json_encode($result, JSON_UNESCAPED_UNICODE);
  151. }
  152. }else{
  153. $this->result["ok"]=false;
  154. $this->result["message"]="email_is_exist";
  155. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  156. }
  157. }
  158. else{
  159. $this->result["ok"]=false;
  160. $this->result["message"]="account_is_exist";
  161. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  162. }
  163. }
  164. #发送密码重置邮件
  165. public function reset_password_send_email(){
  166. $email = $_GET["email"];
  167. $isExist = $this->medoo->has($this->table,["email"=>$email]);
  168. if($isExist){
  169. $resetToken = UUID::v4();
  170. $query = "UPDATE ".$this->table." SET reset_password_token = ? WHERE email = ? ";
  171. $stmt = $this->dbh->prepare($query);
  172. $stmt->execute(array($resetToken,$email));
  173. $ok = true;
  174. //$ok = $this->_update(["reset_password_token"=>$resetToken],["reset_password_token"],["email"=>$email]);
  175. if($ok){
  176. #send email
  177. $resetLink="https://".$_SERVER['SERVER_NAME']."/app/ucenter/reset.php?token=".$resetToken;
  178. $resetString="https://".$_SERVER['SERVER_NAME']."/app/ucenter/reset.php";
  179. // 打开文件并读取数据
  180. $irow=0;
  181. $strSubject = "";
  182. $strBody = "";
  183. if(($fp=fopen("../ucenter/reset_pwd_letter.html", "r"))!==FALSE){
  184. while(($data=fgets($fp))!==FALSE){
  185. $irow++;
  186. if($irow==1){
  187. $strSubject = $data;
  188. }else{
  189. $strBody .= $data;
  190. }
  191. }
  192. fclose($fp);
  193. }
  194. else{
  195. $this->result["ok"] = false;
  196. $this->result["message"] = "can not load email file.";
  197. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  198. return;
  199. }
  200. $strBody = str_replace("%ResetLink%",$resetLink,$strBody);
  201. $strBody = str_replace("%ResetString%",$resetString,$strBody);
  202. //TODO sendmail
  203. //Create an instance; passing `true` enables exceptions
  204. $mail = new PHPMailer(true);
  205. try {
  206. //Server settings
  207. $mail->SMTPDebug = SMTP::DEBUG_OFF; //Enable verbose debug output
  208. $mail->isSMTP(); //Send using SMTP
  209. $mail->Host = Email["Host"]; //Set the SMTP server to send through
  210. $mail->SMTPAuth = Email["SMTPAuth"]; //Enable SMTP authentication
  211. $mail->Username = Email["Username"]; //SMTP username
  212. $mail->Password = Email["Password"]; //SMTP password
  213. $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
  214. $mail->Port = Email["Port"]; //TCP port to connect to 465; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
  215. $mail->CharSet = 'UTF-8';
  216. $mail->Encoding = 'base64';
  217. //Recipients
  218. $mail->setFrom(Email["From"], Email["Sender"]);
  219. $mail->addAddress($email); //Add a recipient Name is optional
  220. //Content
  221. $mail->isHTML(true); //Set email format to HTML
  222. $mail->Subject = $strSubject;
  223. $mail->Body = $strBody;
  224. $mail->AltBody = $strBody;
  225. $mail->send();
  226. #邮件发送成功,修改数据库
  227. $this->_update(["reset_password_sent_at"=>Medoo::raw('datetime(<now>)')],["reset_password_sent_at"],["email"=>$email]);
  228. //邮件地址脱敏
  229. $show_email = mb_substr($email,0,2,"UTF-8") . "****" . strstr($email,"@");
  230. $this->result["message"] = 'Message has been sent to your email : ' . $show_email;
  231. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  232. return;
  233. } catch (Exception $e) {
  234. $this->result["ok"] = false;
  235. $this->result["message"] = "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
  236. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  237. return;
  238. }
  239. }else{
  240. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  241. return;
  242. }
  243. }else{
  244. $this->result["ok"]=false;
  245. $this->result["message"]="::invalid_email";
  246. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  247. }
  248. }
  249. #重置密码
  250. public function reset_password(){
  251. $json = file_get_contents('php://input');
  252. $data = json_decode($json,true);
  253. $isExist = $this->medoo->has($this->table,["username"=>$data["username"],"reset_password_token"=>$data["reset_password_token"]]);
  254. if($isExist){
  255. #reset password
  256. if(!$this->isValidPassword($data["password"])){
  257. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  258. return;
  259. }
  260. $ok = $this->_update(["password"=>md5($data["password"])],["password"],["username"=>$data["username"]]);
  261. if($ok){
  262. #成功后删除reset_password_token
  263. $ok = $this->_update(["reset_password_token"=>null,
  264. "reset_password_sent_at"=>null],
  265. null,
  266. ["username"=>$data["username"]]);
  267. }
  268. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  269. }else{
  270. $this->result["ok"]=false;
  271. $this->result["message"]="::invalid_token";
  272. echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
  273. }
  274. }
  275. private function isValidPassword($password){
  276. if(mb_strlen($password,"UTF-8")<6){
  277. $this->result["ok"]=false;
  278. $this->result["message"]="::password_too_short";
  279. return false;
  280. }
  281. if(mb_strlen($password,"UTF-8")>32){
  282. $this->result["ok"]=false;
  283. $this->result["message"]="::password_too_long";
  284. return false;
  285. }
  286. if(strpos($password," ")!==false){
  287. $this->result["ok"]=false;
  288. $this->result["message"]="::password_invaild_symbol";
  289. return false;
  290. }
  291. return true;
  292. }
  293. private function isValidUsername($username){
  294. if(mb_strlen($username,"UTF-8")>32){
  295. $this->result["ok"]=false;
  296. $this->result["message"]="::username_too_long";
  297. return false;
  298. }
  299. if(mb_strlen($username,"UTF-8")<4){
  300. $this->result["ok"]=false;
  301. $this->result["message"]="::username_too_short";
  302. return false;
  303. }
  304. if(preg_match("/@|\s|\/|[A-Z]/",$username)!==0){
  305. $this->result["ok"]=false;
  306. $this->result["message"]="::username_invaild_symbol";
  307. return false;
  308. }
  309. return true;
  310. }
  311. private function isValidNickName($nickname){
  312. if(mb_strlen($nickname,"UTF-8")>32){
  313. $this->result["ok"]=false;
  314. $this->result["message"]="::nickname_too_long";
  315. return false;
  316. }
  317. if(mb_strlen($nickname,"UTF-8")<1){
  318. $this->result["ok"]=false;
  319. $this->result["message"]="::nickname_too_short";
  320. return false;
  321. }
  322. return true;
  323. }
  324. private function isValidEmail($email){
  325. $isValid = filter_var($email, FILTER_VALIDATE_EMAIL);
  326. if($isValid===false){
  327. $this->result["ok"]=false;
  328. $this->result["message"]="::invaild_email";
  329. }
  330. return $isValid;
  331. }
  332. }
  333. ?>