Просмотр исходного кода

Merge branch 'master' of https://github.com/visuddhinanda/mint

bhikkhu-kosalla-china 4 лет назад
Родитель
Сommit
1973dff7e0

+ 2 - 0
app/.gitignore

@@ -0,0 +1,2 @@
+# misc
+/phpinfo.php

+ 39 - 0
app/api/like.php

@@ -0,0 +1,39 @@
+<?php
+require_once "../db/like.php";
+require_once "../redis/function.php";
+require_once "../public/function.php";
+
+$model = new Like(redis_connect());
+
+switch ($_REQUEST["_method"]) {
+	case 'index':
+		# get
+		$model->index();
+		break;
+	case 'list':
+		# post
+		$model->list();
+		break;
+	case 'create':
+		# post
+		$model->create();
+		break;
+	case 'show':
+		# get
+		$model->show();
+		break;	
+	case 'update':
+		# post
+		$model->update();
+		break;	
+	case 'delete':
+		# get
+		$model->delete();
+		break;	
+	default:
+		# code...
+		break;
+}
+
+
+?>

+ 43 - 0
app/api/user.php

@@ -0,0 +1,43 @@
+<?php
+require_once "../db/user.php";
+require_once "../redis/function.php";
+require_once "../public/function.php";
+
+$model = new User(redis_connect());
+
+switch ($_REQUEST["_method"]) {
+	case 'index':
+		# get
+		$model->index();
+		break;
+	case 'list':
+		# post
+		$model->list();
+		break;
+	case 'create':
+		# post
+		$model->create();
+		break;
+	case 'show':
+		# get
+		$model->show();
+		break;	
+	case 'update':
+		# post
+		$model->update();
+		break;	
+	case 'delete':
+		# get
+		$model->delete();
+		break;
+	case 'reset_email':
+		# get
+		$model->reset_password_send_email();
+		break;	
+	default:
+		# code...
+		break;
+}
+
+
+?>

+ 4 - 1
app/article/article.js

@@ -67,7 +67,10 @@ function collect_load(id) {
 							$("#article_subtitle").html(result.subtitle);
 						}
 						$("#article_author").html(result.username.nickname + "@" + result.username.username);
-						$("#like_div").html("<like restype='collection' resid='"+id+"'></like>");
+						let htmlLike = "";
+						htmlLike += "<like liketype='like' restype='collection' resid='"+id+"'></like>";
+						htmlLike += "<like liketype='favorite' restype='collection' resid='"+id+"'></like>";
+						$("#like_div").html(htmlLike);
 						$("#summary").html(result.summary);
 						$("#contents").html("<div id='content_text'></div><h3>目录</h3><div id='content_toc'></div>");
 

+ 1 - 6
app/article/get.php

@@ -34,12 +34,7 @@ if(isset($_GET["id"])){
 		exit;
 	}
 	#查询权限结束
-	/*
-    PDO_Connect(""._FILE_DB_USER_ARTICLE_);
-    $id=$_GET["id"];
-    $query = "SELECT * FROM article  WHERE id = ? ";
-    $Fetch = PDO_FetchRow($query,array($id));
-	*/
+
 	$Fetch = $article->getInfo($_GET["id"]);
     if($Fetch){
 		$Fetch["content"] = $article->getContent($_GET["id"]);

+ 3 - 8
app/article/index.php

@@ -9,6 +9,8 @@ require_once "../pcdl/html_head.php";
 	<script  src="./article.js"></script>
 
 	<script src="../widget/like.js"></script>
+	<link type="text/css" rel="stylesheet" href="../widget/like.css"/>
+
 	<script src="../widget/click_dropdown.js"></script>
 	<link type="text/css" rel="stylesheet" href="../widget/click_dropdown.css"/>
 
@@ -130,14 +132,7 @@ span.fancytree-node{
 	max-height: 25vw;
     width: max-content;
 }
-like{
-    min-width: 40px;
-    border: 1px solid var(--border-line-color);
-    display: inline-block;
-    border-radius: 5px;
-    margin: 5px;
-    cursor: pointer;
-}
+
 </style>
 
 <?php

+ 1 - 1
app/config.sample.php

@@ -7,7 +7,7 @@ use PHPMailer\PHPMailer\PHPMailer;
 use PHPMailer\PHPMailer\SMTP;
 use PHPMailer\PHPMailer\Exception;
 
-define("Email", ["SMTPDebug"=>SMTP::DEBUG_SERVER,//Enable verbose debug output
+define("Email", ["SMTPDebug"=>SMTP::DEBUG_SERVER,//Enable verbose debug output DEBUG_OFF
 				 "Host"=>"smtp.gmail.com",//Set the SMTP server to send through
 				 "SMTPAuth"=>true,//Enable SMTP authentication
 				 "Username"=>'your@gmail.com',//SMTP username

+ 100 - 0
app/db/like.php

@@ -0,0 +1,100 @@
+<?php
+require_once "../path.php";
+require_once "../db/table.php";
+/*
+CREATE TABLE likes (
+    id            INTEGER      PRIMARY KEY AUTOINCREMENT,
+    like_type     VARCHAR (16) NOT NULL,
+    resource_type VARCHAR (32) NOT NULL,
+    resource_id   CHAR (36)    NOT NULL,
+    user_id       INTEGER      NOT NULL,
+    created_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP     NOT NULL //只做初始化,更新时不自动更新
+);
+*/
+class Like extends Table
+{
+    function __construct($redis=false) {
+		parent::__construct(_FILE_DB_LIKE_, "likes", "", "",$redis);
+    }
+
+	public function  index(){
+		$where["like_type"] = "like";
+		$where["resource_type"] = $_GET["type"];
+		$where["resource_id"] = explode($_GET["id"],",");
+		echo json_encode($this->_index(["resource_id","user_id"],$where), JSON_UNESCAPED_UNICODE);
+	}
+	
+	public function  list(){
+		if(!isset($_COOKIE["userid"])){
+			$userId = $_COOKIE["userid"];
+		}
+
+		$json = file_get_contents('php://input');
+		$data = json_decode($json,true);
+		foreach ($data as $key => $value) {
+			# code...
+			$data[$key]['like']=$this->medoo->count($this->table,[
+											'like_type'=>$value['like_type'],
+											'resource_type'=>$value['resource_type'],
+											'resource_id'=>$value['resource_id'],
+											  ]);
+		}
+		if(isset($_COOKIE["userid"])){
+			$userId = $_COOKIE["userid"];
+			foreach ($data as $key => $value) {
+				# code...
+				$data[$key]['me']=$this->medoo->count($this->table,[
+												'like_type'=>$value['like_type'],
+												'resource_type'=>$value['resource_type'],
+												'resource_id'=>$value['resource_id'],
+												'user_id'=>$userId,
+												]);
+			}
+		}
+
+		$this->result["ok"]=true;
+		$this->result["message"]="";
+		$this->result["data"]=$data;
+		echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+
+	}
+
+
+	public function  create(){
+		if(!isset($_COOKIE["userid"])){
+			return;
+		}
+		$json = file_get_contents('php://input');
+		$data = json_decode($json,true);
+		$data["user_id"] = $_COOKIE["userid"];
+		$isExist = $this->medoo->has("likes",$data);
+		if(!$isExist){
+			echo json_encode($this->_create($data,["like_type","resource_type","resource_id","user_id"]), JSON_UNESCAPED_UNICODE);
+		}
+		else{
+			$this->result["ok"]=false;
+			$this->result["message"]="is exist";
+			echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+		}
+	}
+	
+	public function  delete(){
+		if(!isset($_COOKIE["userid"])){
+			return;
+		}
+		$where["like_type"] = $_GET["like_type"];
+		$where["resource_type"] = $_GET["resource_type"];
+		$where["resource_id"] = $_GET["resource_id"];
+		$where["user_id"] = $_COOKIE["userid"];
+		$row = $this->_delete($where);
+		if($row["data"]>0){
+			$this->result["data"] = $where;
+		}else{
+			$this->result["ok"]=false;
+			$this->result["message"]="no delete";			
+		}
+		echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+	}
+}
+
+?>

+ 11 - 9
app/db/table.php

@@ -1,13 +1,13 @@
 <?php
 require_once "../redis/function.php";
-/*
+
 // Require Composer's autoloader.
 require '../../vendor/autoload.php';
  
 // Using Medoo namespace.
 use Medoo\Medoo;
 
-*/
+
 class Table
 {
     protected $dbh;
@@ -21,7 +21,6 @@ class Table
     function __construct($db,$table,$user="",$password="",$redis=false) {
         $this->dbh = new PDO($db, $user, $password,array(PDO::ATTR_PERSISTENT=>true));
         $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
-		/*
 		$database = new Medoo([
 			// Initialized and connected PDO object.
 			'pdo' => $this->dbh,
@@ -31,7 +30,7 @@ class Table
 		]);
 		
 		$this->medoo = $database;
-		*/
+		
 		$this->redis = $redis;
 		$this->table = $table;
 		$this->result = ["ok"=>true,"message"=>"","data"=>array()];
@@ -52,14 +51,13 @@ class Table
 			# code...
 			$updateDate[$value] = $data[$value];
 		}
-		$updateDate["created_at"] = mTime();
 		$this->medoo->insert(
 			$this->table,
 			$updateDate
 		);
 
-		$newId = $database->id;
-		$this->result["data"] = $newId;
+		$updateDate["id"] = $this->medoo->id();
+		$this->result["data"] = $updateDate;
 		return $this->result;
 	}
 	public function _update($data,$columns,$where=null){
@@ -67,7 +65,6 @@ class Table
 			# code...
 			$updateDate[$value] = $data[$value];
 		}
-		$updateDate["updated_at"] = mTime();
 
 		if($where==null){
 			$where = ["id"=>$data["id"]];
@@ -78,7 +75,7 @@ class Table
 			$where
 		);
 
-		return $this->result;
+		return true;
 	}
 
 	public function _show($columns,$id){
@@ -91,6 +88,7 @@ class Table
 		return $this->result;
 	}
 
+
 	public function _deleteId($id){
 		$output = $this->medoo->delete(
 			$this->table,
@@ -105,6 +103,10 @@ class Table
 			$where
 		);
 		$this->result["data"] = $output->rowCount();
+		if($this->result["data"]==0){
+			$this->result["ok"] = false;
+			$this->result["message"] = ":no delete";
+		}
 		return $this->result;
 	}
 

+ 221 - 0
app/db/user.php

@@ -0,0 +1,221 @@
+<?php
+require_once "../path.php";
+require_once "../db/table.php";
+require_once "../public/function.php";
+// Require Composer's autoloader.
+require_once '../../vendor/autoload.php';
+require_once '../config.php';
+
+// Using Medoo namespace.
+use Medoo\Medoo;
+
+// Require Composer's autoloader.
+use PHPMailer\PHPMailer\PHPMailer;
+use PHPMailer\PHPMailer\SMTP;
+use PHPMailer\PHPMailer\Exception;
+/*
+CREATE TABLE users (
+    id            INTEGER      PRIMARY KEY AUTOINCREMENT,
+    like_type     VARCHAR (16) NOT NULL,
+    resource_type VARCHAR (32) NOT NULL,
+    resource_id   CHAR (36)    NOT NULL,
+    user_id       INTEGER      NOT NULL,
+    created_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP     NOT NULL //只做初始化,更新时不自动更新
+    updated_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL //自动更新
+);
+*/
+class User extends Table
+{
+    function __construct($redis=false) {
+		parent::__construct(_FILE_DB_USERINFO_, "user", "", "",$redis);
+    }
+
+	public function  index(){
+		$where["like_type"] = "like";
+		$where["resource_type"] = $_GET["type"];
+		$where["resource_id"] = explode($_GET["id"],",");
+		echo json_encode($this->_index(["resource_id","user_id"],$where), JSON_UNESCAPED_UNICODE);
+	}
+	
+	public function  list(){
+		if(!isset($_COOKIE["userid"])){
+			$userId = $_COOKIE["userid"];
+		}
+
+		$json = file_get_contents('php://input');
+		$data = json_decode($json,true);
+		foreach ($data as $key => $value) {
+			# code...
+			$data[$key]['like']=$this->medoo->count($this->table,[
+											'like_type'=>$value['like_type'],
+											'resource_type'=>$value['resource_type'],
+											'resource_id'=>$value['resource_id'],
+											  ]);
+		}
+		if(isset($_COOKIE["userid"])){
+			$userId = $_COOKIE["userid"];
+			foreach ($data as $key => $value) {
+				# code...
+				$data[$key]['me']=$this->medoo->count($this->table,[
+												'like_type'=>$value['like_type'],
+												'resource_type'=>$value['resource_type'],
+												'resource_id'=>$value['resource_id'],
+												'user_id'=>$userId,
+												]);
+			}
+		}
+
+		$this->result["ok"]=true;
+		$this->result["message"]="";
+		$this->result["data"]=$data;
+		echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+
+	}
+
+
+	public function  create(){
+		if(!isset($_COOKIE["userid"])){
+			return;
+		}
+		$json = file_get_contents('php://input');
+		$data = json_decode($json,true);
+		$data["user_id"] = $_COOKIE["userid"];
+		$isExist = $this->medoo->has("likes",$data);
+		if(!$isExist){
+			echo json_encode($this->_create($data,["like_type","resource_type","resource_id","user_id"]), JSON_UNESCAPED_UNICODE);
+		}
+		else{
+			$this->result["ok"]=false;
+			$this->result["message"]="is exist";
+			echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+		}
+	}
+	
+	public function  delete(){
+		if(!isset($_COOKIE["userid"])){
+			return;
+		}
+		$where["like_type"] = $_GET["like_type"];
+		$where["resource_type"] = $_GET["resource_type"];
+		$where["resource_id"] = $_GET["resource_id"];
+		$where["user_id"] = $_COOKIE["userid"];
+		$row = $this->_delete($where);
+		if($row["data"]>0){
+			$this->result["data"] = $where;
+		}else{
+			$this->result["ok"]=false;
+			$this->result["message"]="no delete";			
+		}
+		echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+	}
+
+	#发送密码重置邮件
+	public function reset_password_send_email(){
+		$email = $_GET["email"];
+		$isExist = $this->medoo->has($this->table,["email"=>$email]);
+		if($isExist){
+			$resetToken = UUID::v4();
+			$ok = $this->_update(["reset_password_token"=>$resetToken],["reset_password_token"],["email"=>$email]);
+			if($ok){
+				#send email
+				$resetLink="https://www.wikipali.org/ucenter/reset.php?token=".$resetToken;
+				$resetString="https://www.wikipali.org/ucenter/reset.php?token=".$resetToken;
+		
+					// 打开文件并读取数据
+				$irow=0;
+				$strSubject = "";
+				$strBody = "";
+				if(($fp=fopen("../ucenter/reset_pwd_letter.html", "r"))!==FALSE){
+					while(($data=fgets($fp))!==FALSE){
+						$irow++;
+						if($irow==1){
+							$strSubject = $data; 
+						}else{
+							$strBody .= $data; 
+						}
+					}
+					fclose($fp);
+				}
+				else{
+					$this->result["ok"] = false;
+					$this->result["message"] = "can not load email file.";
+					echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+					return;
+				}
+		
+				$strBody = str_replace("%resetLink%",$resetLink,$strBody);
+				$strBody = str_replace("%resetString%",$resetString,$strBody);
+		
+				//TODO sendmail
+		
+				//Create an instance; passing `true` enables exceptions
+				$mail = new PHPMailer(true);
+		
+				try {
+					//Server settings
+					$mail->SMTPDebug = SMTP::DEBUG_OFF;                      //Enable verbose debug output
+					$mail->isSMTP();                                            //Send using SMTP
+					$mail->Host       = Email["Host"];                     //Set the SMTP server to send through
+					$mail->SMTPAuth   = Email["SMTPAuth"];                                   //Enable SMTP authentication
+					$mail->Username   = Email["Username"];                     //SMTP username
+					$mail->Password   = Email["Password"];                               //SMTP password
+					$mail->SMTPSecure = Email["SMTPSecure"];            //Enable implicit TLS encryption
+					$mail->Port       = Email["Port"];                                    //TCP port to connect to 465; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
+		
+					//Recipients
+					$mail->setFrom(Email["From"], Email["Sender"]);
+					$mail->addAddress($email);     //Add a recipient Name is optional
+		
+					//Content
+					$mail->isHTML(true);                                  //Set email format to HTML
+					$mail->Subject = $strSubject;
+					$mail->Body    = $strBody;
+					$mail->AltBody = $strBody;
+		
+					$mail->send();
+					#邮件发送成功,修改数据库
+					$this->_update(["reset_password_sent_at"=>Medoo::raw('datetime(<now>)')],["reset_password_sent_at"],["email"=>$email]);
+					//邮件地址脱敏
+					$show_email = mb_substr($email,0,2,"UTF-8") . "****" . strstr($email,"@");
+					$this->result["message"] = 'Message has been sent to your email : ' . $show_email;
+					echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+					return;
+
+				} catch (Exception $e) {
+					$this->result["ok"] = false;
+					$this->result["message"] = "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
+					echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+					return;
+				}
+			}else{
+				echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+				return;
+			}
+		}else{
+			$this->result["ok"]=false;
+			$this->result["message"]="invalid email";
+			echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+		}
+	}
+
+	#重置密码
+	public function reset_password($username,$password,$token){
+		$isExist = $this->medoo->has($this->table,["user_name"=>$username,"token"=>$token]);
+		if($isExist){
+			#reset password
+			$ok = $this->_update(["password"=>$password],"password",["user_name"=>$username]);
+			if($ok){
+				echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+				
+			}else{
+				echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+			}
+		}else{
+			$this->result["ok"]=false;
+			$this->result["message"]="invalid token";
+			echo json_encode($this->result, JSON_UNESCAPED_UNICODE);
+		}
+	}
+}
+
+?>

+ 4 - 0
app/dbadmin/.gitignore

@@ -0,0 +1,4 @@
+/user/config.php
+/system/config.php
+/3rd/config.php
+/palicanon/config.php

+ 1 - 1
app/studio/dictadmin/3rd/phpliteadmin.config.php → app/dbadmin/3rd/config.sample.php

@@ -13,7 +13,7 @@
 $password = 'dhamma';
 
 //directory relative to this file to search for databases (if false, manually list databases in the $databases variable)
-$directory = '../../../../tmp/appdata/dict/3rd';
+$directory = '../../../tmp/appdata/dict/3rd';
 
 //whether or not to scan the subdirectories of the above directory infinitely deep
 $subdirectories = false;

+ 39 - 55
app/studio/dictadmin/system/pla.php → app/dbadmin/3rd/pla.php

@@ -425,7 +425,7 @@ $lang = array(
 //- Initialization
 
 // load optional configuration file
-$config_filename = './phpliteadmin.config.php';
+$config_filename = './config.php';
 if (is_readable($config_filename))
 {
 	include_once $config_filename;
@@ -442,6 +442,43 @@ define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php');
 define('PROJECT_BUGTRACKER_LINK','<a href="https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open" target="_blank">https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open</a>');
 define('PROJECT_INSTALL_LINK','<a href="https://bitbucket.org/phpliteadmin/public/wiki/Installation" target="_blank">https://bitbucket.org/phpliteadmin/public/wiki/Installation</a>');
 
+class MicroTimer {
+
+	private $startTime, $stopTime;
+
+	// creates and starts a timer
+	function __construct()
+	{
+		$this->startTime = microtime(true);
+	}
+
+	// stops a timer
+	public function stop()
+	{
+		$this->stopTime = microtime(true);
+	}
+
+	// returns the number of seconds from the timer's creation, or elapsed
+	// between creation and call to ->stop()
+	public function elapsed()
+	{
+		if ($this->stopTime)
+			return round($this->stopTime - $this->startTime, 4);
+
+		return round(microtime(true) - $this->startTime, 4);
+	}
+
+	// called when using a MicroTimer object as a string
+	public function __toString()
+	{
+		return (string) $this->elapsed();
+	}
+
+}
+//	class Resources (issue #157)
+//	outputs secondary files, such as css and javascript
+//	data is stored gzipped (gzencode) and encoded (base64_encode)
+//
 // up here, we don't output anything. debug output might appear here which is catched by ob and thrown later
 ob_start();
 
@@ -486,24 +523,7 @@ if($language != 'en') {
 	unset($temp_lang);
 }
 
-// stripslashes if MAGIC QUOTES is turned on
-// This is only a workaround. Please better turn off magic quotes!
-// This code is from http://php.net/manual/en/security.magicquotes.disabling.php
-if (get_magic_quotes_gpc()) {
-	$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
-	while (list($key, $val) = each($process)) {
-		foreach ($val as $k => $v) {
-			unset($process[$key][$k]);
-			if (is_array($v)) {
-				$process[$key][stripslashes($k)] = $v;
-				$process[] = &$process[$key][stripslashes($k)];
-			} else {
-				$process[$key][stripslashes($k)] = stripslashes($v);
-			}
-		}
-	}
-	unset($process);
-}
+
 
 
 //data types array
@@ -5986,43 +6006,7 @@ class GetParameters
 }//	class MicroTimer (issue #146)
 //	wraps calls to microtime(), calculating the elapsed time and rounding output
 //
-class MicroTimer {
-
-	private $startTime, $stopTime;
-
-	// creates and starts a timer
-	function __construct()
-	{
-		$this->startTime = microtime(true);
-	}
-
-	// stops a timer
-	public function stop()
-	{
-		$this->stopTime = microtime(true);
-	}
 
-	// returns the number of seconds from the timer's creation, or elapsed
-	// between creation and call to ->stop()
-	public function elapsed()
-	{
-		if ($this->stopTime)
-			return round($this->stopTime - $this->startTime, 4);
-
-		return round(microtime(true) - $this->startTime, 4);
-	}
-
-	// called when using a MicroTimer object as a string
-	public function __toString()
-	{
-		return (string) $this->elapsed();
-	}
-
-}
-//	class Resources (issue #157)
-//	outputs secondary files, such as css and javascript
-//	data is stored gzipped (gzencode) and encoded (base64_encode)
-//
 class Resources {
 
 	// set this to the file containing getInternalResource;

+ 1 - 1
app/studio/dictadmin/palicanon/phpliteadmin.config.php → app/dbadmin/palicanon/config.sample.php

@@ -13,7 +13,7 @@
 $password = 'dhamma';
 
 //directory relative to this file to search for databases (if false, manually list databases in the $databases variable)
-$directory = "../../../../tmp/appdata/palicanon";
+$directory = "../../../tmp/appdata/palicanon";
 
 //whether or not to scan the subdirectories of the above directory infinitely deep
 $subdirectories = false;

+ 39 - 55
app/studio/dictadmin/3rd/pla.php → app/dbadmin/palicanon/pla.php

@@ -425,7 +425,7 @@ $lang = array(
 //- Initialization
 
 // load optional configuration file
-$config_filename = './phpliteadmin.config.php';
+$config_filename = './config.php';
 if (is_readable($config_filename))
 {
 	include_once $config_filename;
@@ -442,6 +442,43 @@ define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php');
 define('PROJECT_BUGTRACKER_LINK','<a href="https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open" target="_blank">https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open</a>');
 define('PROJECT_INSTALL_LINK','<a href="https://bitbucket.org/phpliteadmin/public/wiki/Installation" target="_blank">https://bitbucket.org/phpliteadmin/public/wiki/Installation</a>');
 
+class MicroTimer {
+
+	private $startTime, $stopTime;
+
+	// creates and starts a timer
+	function __construct()
+	{
+		$this->startTime = microtime(true);
+	}
+
+	// stops a timer
+	public function stop()
+	{
+		$this->stopTime = microtime(true);
+	}
+
+	// returns the number of seconds from the timer's creation, or elapsed
+	// between creation and call to ->stop()
+	public function elapsed()
+	{
+		if ($this->stopTime)
+			return round($this->stopTime - $this->startTime, 4);
+
+		return round(microtime(true) - $this->startTime, 4);
+	}
+
+	// called when using a MicroTimer object as a string
+	public function __toString()
+	{
+		return (string) $this->elapsed();
+	}
+
+}
+//	class Resources (issue #157)
+//	outputs secondary files, such as css and javascript
+//	data is stored gzipped (gzencode) and encoded (base64_encode)
+//
 // up here, we don't output anything. debug output might appear here which is catched by ob and thrown later
 ob_start();
 
@@ -486,24 +523,7 @@ if($language != 'en') {
 	unset($temp_lang);
 }
 
-// stripslashes if MAGIC QUOTES is turned on
-// This is only a workaround. Please better turn off magic quotes!
-// This code is from http://php.net/manual/en/security.magicquotes.disabling.php
-if (get_magic_quotes_gpc()) {
-	$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
-	while (list($key, $val) = each($process)) {
-		foreach ($val as $k => $v) {
-			unset($process[$key][$k]);
-			if (is_array($v)) {
-				$process[$key][stripslashes($k)] = $v;
-				$process[] = &$process[$key][stripslashes($k)];
-			} else {
-				$process[$key][stripslashes($k)] = stripslashes($v);
-			}
-		}
-	}
-	unset($process);
-}
+
 
 
 //data types array
@@ -5986,43 +6006,7 @@ class GetParameters
 }//	class MicroTimer (issue #146)
 //	wraps calls to microtime(), calculating the elapsed time and rounding output
 //
-class MicroTimer {
-
-	private $startTime, $stopTime;
-
-	// creates and starts a timer
-	function __construct()
-	{
-		$this->startTime = microtime(true);
-	}
-
-	// stops a timer
-	public function stop()
-	{
-		$this->stopTime = microtime(true);
-	}
 
-	// returns the number of seconds from the timer's creation, or elapsed
-	// between creation and call to ->stop()
-	public function elapsed()
-	{
-		if ($this->stopTime)
-			return round($this->stopTime - $this->startTime, 4);
-
-		return round(microtime(true) - $this->startTime, 4);
-	}
-
-	// called when using a MicroTimer object as a string
-	public function __toString()
-	{
-		return (string) $this->elapsed();
-	}
-
-}
-//	class Resources (issue #157)
-//	outputs secondary files, such as css and javascript
-//	data is stored gzipped (gzencode) and encoded (base64_encode)
-//
 class Resources {
 
 	// set this to the file containing getInternalResource;

+ 1 - 1
app/studio/dictadmin/system/phpliteadmin.config.php → app/dbadmin/system/config.sample.php

@@ -13,7 +13,7 @@
 $password = 'dhamma';
 
 //directory relative to this file to search for databases (if false, manually list databases in the $databases variable)
-$directory = '../../../../tmp/appdata/dict/system';
+$directory = '../../../tmp/appdata/dict/system';
 
 //whether or not to scan the subdirectories of the above directory infinitely deep
 $subdirectories = false;

+ 39 - 55
app/studio/dictadmin/term/pla.php → app/dbadmin/system/pla.php

@@ -425,7 +425,7 @@ $lang = array(
 //- Initialization
 
 // load optional configuration file
-$config_filename = './phpliteadmin.config.php';
+$config_filename = './config.php';
 if (is_readable($config_filename))
 {
 	include_once $config_filename;
@@ -442,6 +442,43 @@ define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php');
 define('PROJECT_BUGTRACKER_LINK','<a href="https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open" target="_blank">https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open</a>');
 define('PROJECT_INSTALL_LINK','<a href="https://bitbucket.org/phpliteadmin/public/wiki/Installation" target="_blank">https://bitbucket.org/phpliteadmin/public/wiki/Installation</a>');
 
+class MicroTimer {
+
+	private $startTime, $stopTime;
+
+	// creates and starts a timer
+	function __construct()
+	{
+		$this->startTime = microtime(true);
+	}
+
+	// stops a timer
+	public function stop()
+	{
+		$this->stopTime = microtime(true);
+	}
+
+	// returns the number of seconds from the timer's creation, or elapsed
+	// between creation and call to ->stop()
+	public function elapsed()
+	{
+		if ($this->stopTime)
+			return round($this->stopTime - $this->startTime, 4);
+
+		return round(microtime(true) - $this->startTime, 4);
+	}
+
+	// called when using a MicroTimer object as a string
+	public function __toString()
+	{
+		return (string) $this->elapsed();
+	}
+
+}
+//	class Resources (issue #157)
+//	outputs secondary files, such as css and javascript
+//	data is stored gzipped (gzencode) and encoded (base64_encode)
+//
 // up here, we don't output anything. debug output might appear here which is catched by ob and thrown later
 ob_start();
 
@@ -486,24 +523,7 @@ if($language != 'en') {
 	unset($temp_lang);
 }
 
-// stripslashes if MAGIC QUOTES is turned on
-// This is only a workaround. Please better turn off magic quotes!
-// This code is from http://php.net/manual/en/security.magicquotes.disabling.php
-if (get_magic_quotes_gpc()) {
-	$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
-	while (list($key, $val) = each($process)) {
-		foreach ($val as $k => $v) {
-			unset($process[$key][$k]);
-			if (is_array($v)) {
-				$process[$key][stripslashes($k)] = $v;
-				$process[] = &$process[$key][stripslashes($k)];
-			} else {
-				$process[$key][stripslashes($k)] = stripslashes($v);
-			}
-		}
-	}
-	unset($process);
-}
+
 
 
 //data types array
@@ -5986,43 +6006,7 @@ class GetParameters
 }//	class MicroTimer (issue #146)
 //	wraps calls to microtime(), calculating the elapsed time and rounding output
 //
-class MicroTimer {
-
-	private $startTime, $stopTime;
-
-	// creates and starts a timer
-	function __construct()
-	{
-		$this->startTime = microtime(true);
-	}
-
-	// stops a timer
-	public function stop()
-	{
-		$this->stopTime = microtime(true);
-	}
 
-	// returns the number of seconds from the timer's creation, or elapsed
-	// between creation and call to ->stop()
-	public function elapsed()
-	{
-		if ($this->stopTime)
-			return round($this->stopTime - $this->startTime, 4);
-
-		return round(microtime(true) - $this->startTime, 4);
-	}
-
-	// called when using a MicroTimer object as a string
-	public function __toString()
-	{
-		return (string) $this->elapsed();
-	}
-
-}
-//	class Resources (issue #157)
-//	outputs secondary files, such as css and javascript
-//	data is stored gzipped (gzencode) and encoded (base64_encode)
-//
 class Resources {
 
 	// set this to the file containing getInternalResource;

+ 1 - 1
app/studio/dictadmin/user/phpliteadmin.config.php → app/dbadmin/user/config.sample.php

@@ -13,7 +13,7 @@
 $password = 'dhamma';
 
 //directory relative to this file to search for databases (if false, manually list databases in the $databases variable)
-$directory = "../../../../tmp/user";
+$directory = "../../../tmp/user";
 
 //whether or not to scan the subdirectories of the above directory infinitely deep
 $subdirectories = false;

+ 39 - 55
app/studio/dictadmin/palicanon/pla.php → app/dbadmin/user/pla.php

@@ -425,7 +425,7 @@ $lang = array(
 //- Initialization
 
 // load optional configuration file
-$config_filename = './phpliteadmin.config.php';
+$config_filename = './config.php';
 if (is_readable($config_filename))
 {
 	include_once $config_filename;
@@ -442,6 +442,43 @@ define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php');
 define('PROJECT_BUGTRACKER_LINK','<a href="https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open" target="_blank">https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open</a>');
 define('PROJECT_INSTALL_LINK','<a href="https://bitbucket.org/phpliteadmin/public/wiki/Installation" target="_blank">https://bitbucket.org/phpliteadmin/public/wiki/Installation</a>');
 
+class MicroTimer {
+
+	private $startTime, $stopTime;
+
+	// creates and starts a timer
+	function __construct()
+	{
+		$this->startTime = microtime(true);
+	}
+
+	// stops a timer
+	public function stop()
+	{
+		$this->stopTime = microtime(true);
+	}
+
+	// returns the number of seconds from the timer's creation, or elapsed
+	// between creation and call to ->stop()
+	public function elapsed()
+	{
+		if ($this->stopTime)
+			return round($this->stopTime - $this->startTime, 4);
+
+		return round(microtime(true) - $this->startTime, 4);
+	}
+
+	// called when using a MicroTimer object as a string
+	public function __toString()
+	{
+		return (string) $this->elapsed();
+	}
+
+}
+//	class Resources (issue #157)
+//	outputs secondary files, such as css and javascript
+//	data is stored gzipped (gzencode) and encoded (base64_encode)
+//
 // up here, we don't output anything. debug output might appear here which is catched by ob and thrown later
 ob_start();
 
@@ -486,24 +523,7 @@ if($language != 'en') {
 	unset($temp_lang);
 }
 
-// stripslashes if MAGIC QUOTES is turned on
-// This is only a workaround. Please better turn off magic quotes!
-// This code is from http://php.net/manual/en/security.magicquotes.disabling.php
-if (get_magic_quotes_gpc()) {
-	$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
-	while (list($key, $val) = each($process)) {
-		foreach ($val as $k => $v) {
-			unset($process[$key][$k]);
-			if (is_array($v)) {
-				$process[$key][stripslashes($k)] = $v;
-				$process[] = &$process[$key][stripslashes($k)];
-			} else {
-				$process[$key][stripslashes($k)] = stripslashes($v);
-			}
-		}
-	}
-	unset($process);
-}
+
 
 
 //data types array
@@ -5986,43 +6006,7 @@ class GetParameters
 }//	class MicroTimer (issue #146)
 //	wraps calls to microtime(), calculating the elapsed time and rounding output
 //
-class MicroTimer {
-
-	private $startTime, $stopTime;
-
-	// creates and starts a timer
-	function __construct()
-	{
-		$this->startTime = microtime(true);
-	}
-
-	// stops a timer
-	public function stop()
-	{
-		$this->stopTime = microtime(true);
-	}
 
-	// returns the number of seconds from the timer's creation, or elapsed
-	// between creation and call to ->stop()
-	public function elapsed()
-	{
-		if ($this->stopTime)
-			return round($this->stopTime - $this->startTime, 4);
-
-		return round(microtime(true) - $this->startTime, 4);
-	}
-
-	// called when using a MicroTimer object as a string
-	public function __toString()
-	{
-		return (string) $this->elapsed();
-	}
-
-}
-//	class Resources (issue #157)
-//	outputs secondary files, such as css and javascript
-//	data is stored gzipped (gzencode) and encoded (base64_encode)
-//
 class Resources {
 
 	// set this to the file containing getInternalResource;

+ 1 - 43
app/group/group.js

@@ -129,49 +129,7 @@ function group_list(id, list) {
 								result.parent.name +
 								"</a> "
 						);
-					} else {
-						/*
-						关闭子小组功能
-						if (result.info.owner == getCookie("userid")) {
-							$("#button_new_sub_group").show();
-						}
-						//子小组列表
-						html += "<div class='info_block'>";
-						html += "<h2>" + gLocal.gui.sub_group + "</h2>";
-						if (result.children && result.children.length > 0) {
-							for (const iterator of result.children) {
-								html += '<div class="file_list_row" style="padding:5px;">';
-								html += "<div style='flex:1;'>" + key++ + "</div>";
-								html += "<div style='flex:2;'>" + iterator.name + "</div>";
-								html += "<div style='flex:2;'>";
-								if (iterator.owner == getCookie("userid")) {
-									html += gLocal.gui.owner;
-								}
-								html += "</div>";
-								html +=
-									"<div style='flex:1;'><a href='../group/index.php?id=" +
-									iterator.id +
-									"&list=file'>" +
-									gLocal.gui.enter +
-									"</a></div>";
-								html += "<div style='flex:1;'><div class='hover_button'>";
-								if (iterator.owner == getCookie("userid")) {
-									html +=
-										"<button onclick=\"group_del('" +
-										iterator.id +
-										"')\">" +
-										gLocal.gui.delete +
-										"</button>";
-								}
-								html += "</div></div>";
-								html += "</div>";
-							}
-						} else {
-							html += "尚未设置小组";
-						}
-						html += "</div>";
-*/
-					}
+					} 
 
 					//共享文件列表
 					key = 1;

+ 0 - 82
app/studio/dictadmin/term/phpliteadmin.config.php

@@ -1,82 +0,0 @@
-<?php 
-//
-// This is sample configuration file
-//
-// You can configure phpliteadmin in one of 2 ways:
-// 1. Rename phpliteadmin.config.sample.php to phpliteadmin.config.php and change parameters in there.
-//    You can set only your custom settings in phpliteadmin.config.php. All other settings will be set to defaults.
-// 2. Change parameters directly in main phpliteadmin.php file
-//
-// Please see https://bitbucket.org/phpliteadmin/public/wiki/Configuration for more details
-
-//password to gain access
-$password = 'dhamma';
-
-//directory relative to this file to search for databases (if false, manually list databases in the $databases variable)
-$directory = "../../../../tmp/appdata/dict/dhammaterm";
-
-//whether or not to scan the subdirectories of the above directory infinitely deep
-$subdirectories = false;
-
-//if the above $directory variable is set to false, you must specify the databases manually in an array as the next variable
-//if any of the databases do not exist as they are referenced by their path, they will be created automatically
-$databases = array(
-	array(
-		'path'=> 'database1.sqlite',
-		'name'=> 'Database 1'
-	),
-	array(
-		'path'=> 'database2.sqlite',
-		'name'=> 'Database 2'
-	),
-);
-
-
-/* ---- Interface settings ---- */
-
-// Theme! If you want to change theme, save the CSS file in same folder of phpliteadmin or in folder "themes"
-$theme = 'phpliteadmin.css';
-
-// the default language! If you want to change it, save the language file in same folder of phpliteadmin or in folder "languages"
-// More about localizations (downloads, how to translate etc.): https://bitbucket.org/phpliteadmin/public/wiki/Localization
-$language = 'en';
-
-// set default number of rows. You need to relog after changing the number
-$rowsNum = 30;
-
-// reduce string characters by a number bigger than 10
-$charsNum = 300;
-
-// maximum number of SQL queries to save in the history
-$maxSavedQueries = 10;
-
-/* ---- Custom functions ---- */
-
-//a list of custom functions that can be applied to columns in the databases
-//make sure to define every function below if it is not a core PHP function
-$custom_functions = array(
-	'md5', 'sha1', 'time', 'strtotime',
-	// add the names of your custom functions to this array
-	/* 'leet_text', */
-);
-
-// define your custom functions here
-/*
-function leet_text($value)
-{
-  return strtr($value, 'eaAsSOl', '344zZ01');
-}
-*/
-
-
-/* ---- Advanced options ---- */
-
-//changing the following variable allows multiple phpLiteAdmin installs to work under the same domain.
-$cookie_name = 'pla3412';
-
-//whether or not to put the app in debug mode where errors are outputted
-$debug = false;
-
-// the user is allowed to create databases with only these extensions
-$allowed_extensions = array('db','db3','sqlite','sqlite3');
-

Разница между файлами не показана из-за своего большого размера
+ 0 - 6106
app/studio/dictadmin/user/pla.php


+ 1 - 1
app/studio/message.php

@@ -40,7 +40,7 @@ if (isset($_POST["paragraph"])) {
 } else {
     $para = 0;
 }
-if (isset($_COOKIE["username"]) && !empty($_COOKIE["username"])) {
+if (isset($_COOKIE["uid"]) ) {
     $uid = $_COOKIE["uid"];
     $username = $_COOKIE["username"];
 } else {

+ 1 - 1
app/studio/publish.php

@@ -33,7 +33,7 @@ if (isset($_GET["step"])) {
     $step = $_GET["step"];
 }
 
-if ($_COOKIE["userid"]) {
+if ($_COOKIE["uid"]) {
     $userid = $_COOKIE["userid"];
     $uid = $_COOKIE["uid"];
 } else {

+ 244 - 0
app/ucenter/forgot_pwd.php

@@ -0,0 +1,244 @@
+<?php
+#忘记
+require_once '../path.php';
+require_once "../public/load_lang.php";
+require_once "../public/function.php";
+
+?>
+
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link type="text/css" rel="stylesheet" href="../studio/css/font.css"/>
+		<link type="text/css" rel="stylesheet" href="../studio/css/style.css"/>
+		<link type="text/css" rel="stylesheet" href="../studio/css/color_day.css" id="colorchange" />
+		<title>wikipali reset password</title>
+		<script src="../public/js/comm.js"></script>
+		<script src="../studio/js/jquery-3.3.1.min.js"></script>
+		<script src="../studio/js/fixedsticky.js"></script>
+		<style>
+		#login_body{
+			display: flex;
+			padding: 2em;
+			margin: auto;
+		}
+		#login_left {
+			padding-right: 12em;
+			padding-top: 5em;
+		}
+		.title{
+			font-size: 150%;
+			margin-top: 1em;
+			margin-bottom: 0.5em;
+		}
+		#login_form{
+			padding: 2em 0 1em 0;
+		}
+		#tool_bar {
+			padding: 1em;
+			display: flex;
+			justify-content: space-between;
+		}
+		#login_shortcut {
+			display: flex;
+			flex-direction: column;
+			padding: 2em 0;
+		}
+		#login_shortcut button{
+			height:3em;
+		}
+		#button_area{
+			text-align: right;
+				padding: 1em 0;
+		}
+		.form_help{
+			font-weight: 400;
+			color: var(--bookx);
+		}
+		.login_form input{
+			margin-top:2em;
+			padding:0.5em 0.5em;
+		}
+		.login_form select{
+			margin-top:2em;
+			padding:0.5em 0.5em;
+		}
+		.login_form input[type="submit"]{
+			margin-top:2em;
+			padding:0.1em 0.5em;
+		}
+
+		.form_error{
+			color:var(--error-text);
+		}
+		#login_form_div{
+			width:30em;
+		}
+
+		#ucenter_body {
+			display: flex;
+			flex-direction: column;
+			margin: 0;
+			padding: 0;
+			background-color: var(--tool-bg-color3);
+			color: var(--btn-color);
+		}
+		.icon_big {
+			height: 2em;
+			width: 2em;
+			fill: var(--btn-color);
+			transition: all 0.2s ease;
+		}
+		.form_field_name{
+			position: absolute;
+			margin-left: 7px;
+			margin-top: 2em;
+			color: var(--btn-border-line-color);
+			-webkit-transition-duration: 0.4s;
+			-moz-transition-duration: 0.4s;
+			transition-duration: 0.4s;
+			transform: translateY(0.5em);
+		}
+		.viewswitch_on {
+			position: absolute;
+			margin-left: 7px;
+			margin-top: 1.5em;
+			color: var(--bookx);
+			-webkit-transition-duration: 0.4s;
+			-moz-transition-duration: 0.4s;
+			transition-duration: 0.4s;
+			transform: translateY(-15px);
+		}
+
+		</style>
+
+		<script>
+
+		function login_init(){
+			$("input").focus(function(){
+				let name = $(this).attr("name");
+				var objNave = document.getElementById("tip_"+name);
+				objNave.className = "viewswitch_on";
+			});
+			$(".form_field_name").click(function(){
+				let id = $(this).attr("id");
+				var objNave = document.getElementById(id);
+				objNave.className = "viewswitch_on";
+				let arrId=id.split("_");
+				document.getElementById('input_'+arrId[1]).focus();
+			});
+
+		}
+		</script>
+	<link type="text/css" rel="stylesheet" href="mobile.css" media="screen and (max-width:800px)">
+	</head>
+	<body id="ucenter_body" onload="login_init()">
+
+	<div id="tool_bar">
+	</div>
+<div id="login_body" >
+
+	<div id="login_left">
+		<div  >
+			<svg  style="height: 8em;width: 25em;">
+				<use xlink:href="../public/images/svg/wikipali_login_page.svg#logo_login"></use>
+			</svg>
+		</div>
+		<div style="    padding: 1em 0 0 3.5em;font-weight: 400;">
+		<?php echo $_local->gui->pali_literature_platform; ?>
+		<ul style="padding-left: 1.2em;">
+			<li><?php echo $_local->gui->online_dict_db; ?></li>
+			<li><?php echo $_local->gui->user_data_share; ?></li>
+			<li><?php echo $_local->gui->cooperate_edit; ?></li>
+		</ul>
+		</div>
+	</div>
+	<div id="login_right">
+		<div id = "login_form_div" class="fun_block" >
+
+			<div class="title">
+			忘记密码?
+			</div>
+			<div class="login_new">
+				<span class="form_help"><?php echo $_local->gui->have_account; ?> ?</span><a href="index.php?language=<?php echo $currLanguage; ?>">&nbsp;&nbsp;&nbsp;&nbsp;<?php echo $_local->gui->login; //登入账户 ?></a>
+			</div>
+
+			<div class="login_form" style="    padding: 3em 0 3em 0;">
+			<div class="form_help">
+				我们将向您的注册邮箱发送电子邮件。里面包含了重置密码链接。点击链接后按照提示操作,重置账户密码。
+			</div>
+			<div class="form_help" id="message"> </div>			
+				<form action="../api/user.php" method="get">
+					<div>
+						<div>
+							<span id='tip_email' class='form_field_name'><?php echo $_local->gui->email_address; ?></span>
+							<input id="form_email" type="input" name="email"  value="" />
+						</div>
+						<div id="error_email" class="form_error"> </div>
+						<div class="form_help"></div>
+					</div>
+
+					<input type="hidden" name="_method" value="reset_email" />
+
+
+				</form>
+					<div id="button_area">
+						<button  onclick="submit()" style="background-color: var(--link-hover-color);border-color: var(--link-hover-color);" >
+						<?php echo $_local->gui->continue; ?>
+						</button>
+					</div>				
+			</div>
+		</div>
+	</div>
+</div>
+
+	<script>
+	login_init();
+		function submit(){
+			$.getJSON(
+		"../api/user.php",
+		{
+			_method:"reset_email",
+			email:$("#form_email").val()
+		}
+	).done(function (data) {
+		$("#message").text(data.message);
+		if(data.ok){
+			$("#message").removeClass("form_error");
+		}else{
+			$("#message").addClass("form_error");
+		}
+	}).fail(function(jqXHR, textStatus, errorThrown){
+		$("#message").removeClass("form_error");
+		$("#message").text(textStatus);				
+		switch (textStatus) {
+	
+			case "timeout":
+				break;
+			case "error":
+				switch (jqXHR.status) {
+					case 404:
+						break;
+					case 500:
+						break;				
+					default:
+						break;
+				}
+				break;
+			case "abort":
+				break;
+			case "parsererror":			
+				console.log("delete-parsererror",jqXHR.responseText);
+				break;
+			default:
+				break;
+		}
+		
+	});
+		}
+	</script>
+
+	</body>
+</html>

+ 18 - 1
app/ucenter/function.php

@@ -44,7 +44,7 @@ class UserInfo
     private $buffer;
     public function __construct()
     {
-        $dns = "" . _FILE_DB_USERINFO_;
+        $dns = _FILE_DB_USERINFO_;
         $this->dbh = new PDO($dns, "", "", array(PDO::ATTR_PERSISTENT => true));
         $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
         $buffer = array();
@@ -75,6 +75,23 @@ class UserInfo
             return $buffer[$id];
         }
 	}
+	public function getId($uuid)
+    {
+        if (empty($uuid)) {
+            return 0;
+        }
+        if ($this->dbh) {
+            $query = "SELECT id FROM user WHERE  userid= ? ";
+            $stmt = $this->dbh->prepare($query);
+            $stmt->execute(array($uuid));
+            $user = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($user) {
+                return $user["id"];
+            }
+        } else {
+            return 0;
+        }
+	}
 	public function check_password($userid,$password){
 		if ($this->dbh) {
             $query = "SELECT username FROM user WHERE  userid= ? and password = ? ";

+ 186 - 117
app/ucenter/index.php

@@ -3,42 +3,57 @@ require_once '../path.php';
 require_once "../public/load_lang.php";
 require_once "../public/_pdo.php";
 require_once "../public/function.php";
+require_once "../redis/function.php";
 
-if (isset($_GET["op"])) {
-    $op = $_GET["op"];
+
+if (isset($_REQUEST["op"])) {
+    $op = $_REQUEST["op"];
 } else {
     $op = "login";
 }
 
 switch ($op) {
     case "login":
-        {
-            if (isset($_GET["url"])) {
-                $goto_url = $_GET["url"];
-            }
-            break;
-        }
+		if (isset($_GET["url"])) {
+			$goto_url = $_GET["url"];
+		}
+		break;
     case "logout":
-        {
-            if (isset($_COOKIE["nickname"])) {
-                $message_comm = $_local->gui->user . " " . $_COOKIE["nickname"] . " " . $_local->gui->loged_out;
-            }
-            setcookie("uid", "", time() - 60, "/");
-            setcookie("username", "", time() - 60, "/");
-            setcookie("userid", "", time() - 60, "/");
-            setcookie("nickname", "", time() - 60, "/");
-            setcookie("email", "", time() - 60, "/");
-            break;
-        }
+		if (isset($_COOKIE["username"])) {
+			$message_comm = $_local->gui->user . " " . $_COOKIE["username"] . " " . $_local->gui->loged_out;
+		}
+		setcookie("user_uid", "", time() - 60, "/");
+		setcookie("user_id", "", time() - 60, "/");
+
+		setcookie("uid", "", time() - 60, "/");
+		setcookie("username", "", time() - 60, "/");
+		setcookie("userid", "", time() - 60, "/");
+		setcookie("nickname", "", time() - 60, "/");
+		setcookie("email", "", time() - 60, "/");
+
+		break;
     case "new":
-        {
-            $host = $_SERVER['HTTP_HOST'];
-            if (strpos($host, "wikipali.org") !== false) {
-                echo "网站正处于开发阶段。目前不支持注册。";
-                exit;
-            }
-            break;
-        }
+		$host = $_SERVER['HTTP_HOST'];
+		//if (strpos($host, "wikipali.org") !== false) 
+		{
+			if(isset($_REQUEST["invite"])){
+				$redis = redis_connect();
+				if ($redis == false) {
+					echo "no redis connect\n";
+					exit;
+				}
+				$code = $redis->exists("invitecode://".$_REQUEST["invite"]);
+				if(!$code){
+					echo "无效的邀请码,或邀请码已经过期。";
+					exit;
+				}
+				$invite_email = $redis->get("invitecode://".$_REQUEST["invite"]);
+			}else{
+				echo "无邀请码";
+				exit;	
+			}
+		}
+		break;
 }
 
 $post_nickname = "";
@@ -46,55 +61,73 @@ $post_username = "";
 $post_password = "";
 $post_email = "";
 if (isset($_POST["op"]) && $_POST["op"] == "new") {
+	PDO_Connect( _FILE_DB_USERINFO_);
+	//建立账号
     $op = "new";
-    $post_username = $_POST["username"];
-    $post_password = $_POST["password"];
-    $post_nickname = $_POST["nickname"];
-    $post_email = $_POST["email"];
+    $post_username = trim($_POST["username"]);
+    $post_password = trim($_POST["password"]);
+    $post_nickname = trim($_POST["nickname"]);
+    $post_email = trim($_POST["email"]);
+	$post_error = false;
     if (empty($post_username)) {
         $error_username = $_local->gui->account . $_local->gui->cannot_empty;
+		$post_error = true;
     }
+	else{
+        $query = "select count(*) as co from user where username = ?" ;
+        $iFetch = PDO_FetchOne($query,array($post_username));
+        if ($iFetch > 0) { //username is existed
+            $error_username = $_local->gui->account_existed;
+			$post_error = true;
+        }
+	}
+	if (empty($post_email)) {
+        $error_email = $_local->gui->email . $_local->gui->cannot_empty;
+		$post_error = true;
+    }else{
+		$query = "select count(*) as co from user where email = ?" ;
+		$iFetch = PDO_FetchOne($query,array($post_email));
+		if ($iFetch > 0) { //username is existed
+			$error_email = $_local->gui->email . "已经存在";
+			$post_error = true;
+		} 
+	}
     if (empty($post_password)) {
         $error_password = $_local->gui->password . $_local->gui->cannot_empty;
-    }
+		$post_error = true;
+    }else{
+		if(strlen($post_password)<6){
+			$error_password = $_local->gui->password . "过短";
+			$post_error = true;
+		}
+	}
+
     if (empty($post_nickname)) {
         $error_nickname = $_local->gui->nick_name . $_local->gui->cannot_empty;
+		$post_error = true;
     }
-    if (!empty($post_username) && !empty($post_password) && !empty($post_nickname)) {
+
+    if (!$post_error) {
         $md5_password = md5($post_password);
         $new_userid = UUID::v4();
-        PDO_Connect("" . _FILE_DB_USERINFO_);
-        $query = "select * from user where \"username\"=" . $PDO->quote($post_username);
-        $Fetch = PDO_FetchAll($query);
-        $iFetch = count($Fetch);
-        if ($iFetch > 0) { //username is existed
-            $error_username = $_local->gui->account_existed;
-        } else {
-            $query = "INSERT INTO user ('id','userid','username','password','nickname','email') VALUES (NULL," . $PDO->quote($new_userid) . "," . $PDO->quote($post_username) . "," . $PDO->quote($md5_password) . "," . $PDO->quote($post_nickname) . "," . $PDO->quote($post_email) . ")";
-            $stmt = @PDO_Execute($query);
-            if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
-                $error = PDO_ErrorInfo();
-                $error_comm = $error[2] . "抱歉!请再试一次";
-            } else {
-                //created user recorder
-                $newUserPath = _DIR_USER_DOC_ . '/' . $new_userid;
-                $userDirMyDocument = $newUserPath . _DIR_MYDOCUMENT_;
-                if (!file_exists($newUserPath)) {
-                    if (mkdir($newUserPath)) {
-                        mkdir($userDirMyDocument);
-                    } else {
-                        $error_comm = "建立用户目录失败,请联络网站管理员。";
-                    }
-                }
-                $message_comm = "新账户建立成功";
-                $op = "login";
-                unset($_POST["username"]);
-            }
-        }
-    } else {
+ 
+				$query = "INSERT INTO user ('id','userid','username','password','nickname','email') VALUES (NULL," . $PDO->quote($new_userid) . "," . $PDO->quote($post_username) . "," . $PDO->quote($md5_password) . "," . $PDO->quote($post_nickname) . "," . $PDO->quote($post_email) . ")";
+				$stmt = @PDO_Execute($query);
+				if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+					$error = PDO_ErrorInfo();
+					$error_comm = $error[2] . "系统错误,抱歉!请再试一次";
+				} else {
+					$message_comm = "新账户建立成功";
+					$op = "login";
+					unset($_POST["username"]);
+					//TODO create channel
+					
+					//TODO create studio
+				}
 
     }
 } else {
+	//登录
     if (isset($_POST["username"])) {
         $_username_ok = true;
         if ($_POST["username"] == "") {
@@ -106,41 +139,50 @@ if (isset($_POST["op"]) && $_POST["op"] == "new") {
             $query = "select * from user where (\"username\"=" . $PDO->quote($_POST["username"]) . " or \"email\"=" . $PDO->quote($_POST["username"]) . " ) and \"password\"=" . $PDO->quote($md5_password);
             $Fetch = PDO_FetchAll($query);
             $iFetch = count($Fetch);
-            if ($iFetch > 0) { //username is exite
+            if ($iFetch > 0) { 
+				//username is exite
                 $uid = $Fetch[0]["id"];
                 $username = $Fetch[0]["username"];
-                $userid = $Fetch[0]["userid"];
+                $user_uuid = $Fetch[0]["userid"];
                 $nickname = $Fetch[0]["nickname"];
                 $email = $Fetch[0]["email"];
-                setcookie("uid", $uid, time() + 60 * 60 * 24 * 365, "/");
-                setcookie("username", $username, time() + 60 * 60 * 24 * 365, "/");
-                setcookie("userid", $userid, time() + 60 * 60 * 24 * 365, "/");
-                setcookie("nickname", $nickname, time() + 60 * 60 * 24 * 365, "/");
-                setcookie("email", $email, time() + 60 * 60 * 24 * 365, "/");
+				$ExpTime = time() + 60 * 60 * 24 * 365;
+				if(empty($_SERVER["HTTPS"])){
+					setcookie("user_uid", $user_uuid,["expires"=>$ExpTime,"path"=>"/","secure"=>false,"httponly"=>true]);
+					setcookie("user_id", $Fetch[0]["id"], ["expires"=>$ExpTime,"path"=>"/","secure"=>false,"httponly"=>true]);
+				}else{
+					setcookie("user_uid", $user_uuid, ["expires"=>$ExpTime,"path"=>"/","secure"=>true,"httponly"=>true]);
+					setcookie("user_id", $Fetch[0]["id"], ["expires"=>$ExpTime,"path"=>"/","secure"=>true,"httponly"=>true]);
+				}
+				#给js用的
+				setcookie("uid", $uid, time()+60*60*24*365,"/");
+				setcookie("username", $username, time()+60*60*24*365,"/");
+				setcookie("userid", $user_uuid, time()+60*60*24*365,"/");
+				setcookie("nickname", $nickname, time()+60*60*24*365,"/");
+				setcookie("email", $email, time()+60*60*24*365,"/");
+
                 if (isset($_POST["url"])) {
                     $goto_url = $_POST["url"];
                 }
+				#设置新密码
                 if (isset($_COOKIE["url"])) {
                     setcookie("pwd_set", "on", time() + 60, "/");
                 }
-                $newUserPath = _DIR_USER_DOC_ . '/' . $userid . '/';
-                if (!file_exists($newUserPath)) {
-                    echo "error:cannot find user dir:$newUserPath<br/>";
-                }
                 ?>
 
+
 <!DOCTYPE html>
 <html>
 	<head>
 
 		<title>wikipali starting</title>
 		<?php
-if (isset($goto_url)) {
+		if (isset($goto_url)) {
                     $goto = $goto_url;
                 } else {
                     $goto = "../studio/index.php";
                 }
-                ?>
+            ?>
 		<meta http-equiv="refresh" content="0,<?php echo $goto; ?>"/>
 	</head>
 
@@ -155,13 +197,14 @@ if (isset($goto_url)) {
 
                 exit;
             } else {
+				//用户名不存在
                 $_post_error = $_local->gui->incorrect_ID_PASS;
             }
         }
     }
 }
 ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
@@ -319,10 +362,7 @@ require_once '../lang/lang.php';
 		<div id = "login_form_div" class="fun_block" >
 
 		<?php
-$host = $_SERVER['HTTP_HOST'];
-if (strpos($host, "wikipali.org") !== false) {
-    echo "网站正处于开发阶段。目前不支持注册。";
-}
+
 if (isset($error_comm)) {
     echo '<div class="form_error">';
     echo $error_comm;
@@ -344,63 +384,90 @@ if ($op == "new") {
 			<div class="login_form" style="    padding: 3em 0 3em 0;">
 			<form action="index.php" method="post">
 				<div>
+
 				<div>
-				    <span id='tip_nickname' class='form_field_name'><?php echo $_local->gui->nick_name; ?></span>
-					<input type="input" name="nickname" value="<?php echo $nickname; ?>" />
-				</div>
-					<div class="form_help">
-						<?php echo $_local->gui->name_for_show; ?>
+						<span id='tip_username' class='form_field_name'><?php echo $_local->gui->account; ?></span>
+						<input type="input" name="username"  value="<?php echo $post_username; ?>" />
 					</div>
-
-					<div id="error_nickname" class="form_error">
-						<?php
-if (isset($error_nickname)) {echo $error_nickname;}
-    ?>
+					<div id="error_username" class="form_error">
+					<?php
+					if (isset($error_username)) {echo $error_username;}
+					?>
 					</div>
-					<div>
-					<select name="language" style="width: 100%;">
-						<option><?php echo $_local->language->en; ?></option>
-						<option><?php echo $_local->language->zh_cn; ?></option>
-						<option><?php echo $_local->language->zh_tw; ?></option>
-						<option><?php echo $_local->language->my; ?></option>
-						<option><?php echo $_local->language->si; ?></option>
-					</select>
+					<div class="form_help">
+						<?php echo $_local->gui->account_demond; ?>
 					</div>
 
 					<div>
 						<span id='tip_email' class='form_field_name'><?php echo $_local->gui->email_address; ?></span>
 						<input type="input" name="email"  value="<?php echo $post_email; ?>" />
-					</div>
-
-					<div>
-						<span id='tip_username' class='form_field_name'><?php echo $_local->gui->account; ?></span>
-						<input type="input" name="username"  value="<?php echo $post_username; ?>" />
-					</div>
-
-					<div id="error_username" class="form_error">
+						<div id="error_email" class="form_error">
 						<?php
-if (isset($error_username)) {echo $error_username;}
-    ?>
+						if (isset($error_email)) {echo $error_email;}
+						?>
+						</div>
 					</div>
 
-					<div class="form_help">
-						<?php echo $_local->gui->account_demond; ?>
-					</div>
 					<div>
 						<span id='tip_password' class='form_field_name'><?php echo $_local->gui->password; ?></span>
-						<input type="password" name="password"  value="<?php echo $post_password; ?>" />
-						<input type="password" name="repassword"  value="<?php echo $post_password; ?>" />
+						<input type="password" name="password" placeholder="密码" value="<?php echo $post_password; ?>" />
+						<input type="password" name="repassword" placeholder="再次输入密码" value="<?php echo $post_password; ?>" />
 					</div>
 					<div class="form_help">
 					<?php echo $_local->gui->password_demond; ?>
 					</div>
-
 					<div id="error_password" class="form_error">
 					<?php
-if (isset($error_password)) {echo $error_password;}
-    ?>
+					if (isset($error_password)) {echo $error_password;}
+					?>
+					</div>
+
+					<div>
+
+						<span id='tip_language' class='viewswitch_on'><?php echo "惯常使用的语言"; ?></span>
+						<select name="language" style="width: 100%;">
+						<?php
+						$currLang = $_COOKIE["language"];
+						$langList = [
+										"en"=>$_local->language->en,
+										"zh-cn"=>$_local->language->zh_cn,
+										"zh-tw"=>$_local->language->zh_tw,
+										"my"=>$_local->language->my,
+										"si"=>$_local->language->si,
+						];
+						foreach ($langList as $key => $value) {
+							# code...
+							if($currLang==$key){
+								$selected = " selected";
+							}else{
+								$selected = "";
+							}
+							echo "<option value='{$key}' {$selected}>{$value}</option>";
+						}
+						?>
+						</select>
 					</div>
+
+					<div>
+						<span id='tip_nickname' class='form_field_name'><?php echo $_local->gui->nick_name; ?></span>
+						<input type="input" name="nickname" value="<?php echo $post_nickname; ?>" />
+					</div>
+					<?php
+						if (isset($error_nickname)) {
+							echo '<div id="error_nickname" class="form_error">';
+							echo $error_nickname;
+							echo '</div>';
+						}
+						else{
+							echo '<div class="form_help">';
+							echo $_local->gui->name_for_show;
+							echo '</div>';
+
+						}
+					?>
+
 					<input type="hidden" name="op" value="new" />
+					<input type="hidden" name="invite" value="<?php echo $_REQUEST["invite"]; ?>" />
 				</div>
 				<div id="button_area">
 					<input type="submit" value="<?php echo $_local->gui->continue; ?>" style="background-color: var(--link-hover-color);border-color: var(--link-hover-color);" />
@@ -464,7 +531,8 @@ if (isset($goto_url)) {
 				</div>
 				</form>
 			</div>
-			<div id="login_shortcut">
+
+			<div id="login_shortcut" style="display:none;">
 				<button class="form_help"><?php echo $_local->gui->login_with_google; ?>&nbsp;
 					<svg class="icon">
 						<use xlink:href="../studio/svg/icon.svg#google_logo"></use>
@@ -481,6 +549,7 @@ if (isset($goto_url)) {
 					</svg>
 				</button>
 			</div>
+
 			<?php
 }
 ?>

+ 2 - 2
app/ucenter/login.php

@@ -8,12 +8,12 @@
  $UID = "";
  $USER_NAME = "";
  $NICK_NAME = "";
-if(isset($_COOKIE["username"]) && !empty($_COOKIE["username"])){
+if(isset($_COOKIE["userid"])){
 //已经登陆
  $USER_ID = $_COOKIE["userid"];
  $UID = $_COOKIE["uid"];
  $USER_NAME = $_COOKIE["username"];
- $NICK_NAME = $_COOKIE["nickname"];
+
  
  $username = $_COOKIE["username"];
  $userid = $_COOKIE["userid"];

+ 13 - 0
app/ucenter/reset_pwd_letter.html

@@ -0,0 +1,13 @@
+wikipali reset password
+<p>
+您收到这封邮件是因为系统接到您的账号需要重置密码的申请。<br>
+如果您没有进行过此操作请忽略这个邮件。
+</p>
+<p>
+点击此链接重置您的wikipali账号的密码。
+<a href="%ResetLink%">%ResetString%</a>
+</p>
+<p>
+	此链接包含重置密码所需要的密钥。请勿发给他人。
+	此邮件为系统自动发送,请勿回复。
+</p>

+ 1 - 12
app/ucenter/user.php

@@ -80,7 +80,7 @@
 		<div class="header-dropdown-content right-content" id="user_info">
 			<div id="user_info_welcome">
 				<div id="user_info_welcome1"><?php echo $_local->gui->welcome; ?></div>
-				<div id="user_info_name"><?php echo $_COOKIE["nickname"]; ?></div>
+				<div id="user_info_name"><?php echo urldecode($_COOKIE["nickname"]); ?></div>
 				<div id="user_info_welcome2"><?php echo $_local->gui->to_the_dhamma; ?></div>
 			</div>
 			<div style="padding:10px; white-space:nowrap;">
@@ -93,17 +93,6 @@
 						?>
 					</span>
 				</a>
-				<!--
-				<a href="../sync" target="_blank" >
-					<span>
-						<svg class="icon">
-							<use xlink:href="../studio/svg/icon.svg#ic_autorenew_24px"></use>
-						</svg>
-						<?php echo $_local->gui->sync; //同步数据
-						?>
-					</span>
-				</a>
-				-->
 				<a href='../uhome/index.php?userid=<?php echo $_COOKIE["userid"]; ?>'>
 					<svg class="icon">
 						<use xlink:href="../studio/svg/icon.svg#my_zone"></use>

+ 15 - 0
app/widget/like.css

@@ -0,0 +1,15 @@
+.like_mine {
+    background-color: var(--btn-bg-color);
+}
+.like_inner {
+    border-radius: 5px;
+    margin: 5px;
+    cursor: pointer;
+    min-width: 40px;
+    border: 1px solid var(--border-line-color);		
+	padding: 2px 8px;
+}
+
+like{
+    display: inline-block;
+}

+ 159 - 0
app/widget/like.js

@@ -0,0 +1,159 @@
+var arrElement = new Array();
+function Like (){
+	$("like").each(function(){
+		if($(this).attr("init")!="true"){
+			arrElement.push({
+							like_type:$(this).attr("liketype"),
+							resource_type:$(this).attr("restype"),
+							resource_id:$(this).attr("resid"),
+							like:0,
+							me:0,
+							init:false
+						});
+		}
+	});
+	$("like").on("click",function(){
+			let liketype = $(this).attr("liketype");
+			let rettype = $(this).attr("restype");
+			let resid = $(this).attr("resid");		
+		let e = arrElement.find(function(item){
+
+			if(liketype===item.like_type && rettype===item.resource_type && resid===item.resource_id){
+				return true;
+			}
+			else{
+				return false;
+			}
+		});
+		if(e.me==0 ){
+			add(e.like_type,e.resource_type,e.resource_id);				
+		}else{
+			remove(e.like_type,e.resource_type,e.resource_id);	
+		}
+	})
+	LikeRefreshAll();
+}
+function add(liketype,restype,resid) {
+	$.ajaxSetup({contentType: "application/json; charset=utf-8"});
+	$.post(
+		"../api/like.php?_method=create",
+		JSON.stringify({
+			like_type:liketype,
+			resource_type:restype,
+			resource_id:resid
+		})
+		
+	).done(function (data) {
+		console.log(data);
+		let result = JSON.parse(data);
+		if(result.ok==true){
+			for (let it of arrElement) {
+				if(result["data"].resource_type===it.resource_type &&
+				result["data"].resource_id===it.resource_id &&
+				result["data"].like_type===it.like_type){
+					it.like++;
+					it.me=1;
+				}
+			}
+			Render();
+		}
+		
+	});
+}
+function remove(liketype,restype,resid) {
+	$.getJSON(
+		"../api/like.php",
+		{
+			_method:"delete",
+			like_type:liketype,
+			resource_type:restype,
+			resource_id:resid
+		}
+	).done(function (data) {
+		console.log("delete",data);
+		if(data.ok){
+			LikeRefresh(data.data);
+		}
+	}).fail(function(jqXHR, textStatus, errorThrown){
+		switch (textStatus) {
+			case "timeout":
+				break;
+			case "error":
+				switch (jqXHR.status) {
+					case 404:
+						break;
+					case 500:
+						break;				
+					default:
+						break;
+				}
+				break;
+			case "abort":
+				break;
+			case "parsererror":
+				console.log("delete-parsererror",jqXHR.responseText);
+				break;
+			default:
+				break;
+		}
+		
+	});
+}
+function LikeRefresh(data){
+	$.ajaxSetup({contentType: "application/json; charset=utf-8"});
+	$.post(
+		"../api/like.php?_method=list",
+		JSON.stringify([data])
+	).done(function (data) {
+		console.log(data);
+		let result = JSON.parse(data);
+		for (let it of arrElement) {
+			if(result["data"][0].resource_type===it.resource_type &&
+			result["data"][0].resource_id===it.resource_id &&
+			result["data"][0].like_type===it.like_type){
+				it.like=result["data"][0].like;
+				it.me=result["data"][0].me;
+			}
+		}
+		Render();
+	});
+}
+
+function LikeRefreshAll(){
+	$.ajaxSetup({contentType: "application/json; charset=utf-8"});
+	$.post(
+		"../api/like.php?_method=list",
+		JSON.stringify(arrElement)
+	).done(function (data) {
+		console.log(data);
+		arrElement = JSON.parse(data).data;
+		Render();
+	});
+}
+
+function Render(){
+	for (const it of arrElement) {
+		let html=" ";
+		let meClass="";
+		let likeIcon="";
+		switch (it.like_type) {
+			case "like":
+				likeIcon = "👍";
+				break;
+			case "favorite":
+				likeIcon = "⭐";
+				break;
+			case "watch":
+				likeIcon = "👁️";
+				break;
+			default:
+				break;
+		}
+		if(it.me>0){
+			meClass = " like_mine";
+		}
+		html +="<div class='like_inner "+meClass+"'>"+likeIcon+it.like+"</div>";
+
+		$("like[liketype='"+it.like_type+"'][restype='"+it.resource_type+"'][resid='"+it.resource_id+"']").html(html);
+	}
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов