The backend of CRSC2014 guestbook for Yu-Ren Pan! Using PHP(>5.3), SQLite3. With a little tweak, you can use PDO to rewrite it so that you can run it in PHP 5.1.
By Andy Pan H1296. Have fun!
<?php | |
//Comment for easier reading | |
// Override default SQLite constructor to | |
// open the file at first. | |
class MyDB extends SQLite3{ | |
function __construct(){ | |
$this->open('dbstore/gb.sqlite'); | |
} | |
} | |
//Email regex for validation | |
$regex_email="/^[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+)*" | |
."@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i"; | |
//Auth! | |
//You can arbitally set this value | |
// but do not expose it | |
$PASS_SALT="madebyandy1296"; | |
//The most important part! The password | |
// shown is 'banana' | |
$PASS_SHA1="198df1ceb81e0f70943b0da0fcf68f2b845b060a"; | |
$isAdmin=isset($_POST["pass"])&&sha1($_POST["pass"].$PASS_SALT)===$PASS_SHA1; | |
function normalizeNL($str){ | |
return preg_replace("/\R/u", "\n", $str); | |
} | |
function makeFlaggedMessage($data){ | |
return array( | |
"no"=>$data["no"], | |
"flagged"=>true, | |
"comment"=>"管理員已經刪除此訊息!", | |
"timestamp"=>$data["timestamp"] | |
); | |
} | |
//Send header so that the content will be recognized as JSON. | |
header( 'Content-type: application/json' ); | |
$db = new MyDB(); | |
$action=$_GET["action"]; | |
function writeData(){ | |
global $db,$data,$regex_email,$info,$isAdmin; | |
//Truncate the incoming data | |
$_POST["name"]=substr($_POST["name"],0,24); | |
$_POST["comment"]=substr($_POST["comment"],0,1024); | |
//normalize newline characters | |
$_POST["comment"]=normalizeNL($_POST["comment"]); | |
$stmt=$db->prepare("insert into book (`category`,`name`,`email`,`comment`,`related`,`by_admin`)" | |
." values (?,?,?,?,?,?)"); | |
if(!$_POST["name"]||!$_POST["comment"]) | |
return "Some parameters are missing!"; | |
if($_POST["email"]){ | |
$vali=preg_match($regex_email,$_POST["email"]); | |
if($vali===0){ | |
return "Email is not valid!"; | |
}else if(!$vali){ | |
return "Error occured while validating email."; | |
} | |
} | |
if($_POST["related"]){ | |
$stmt_count=$db->prepare("select category from book where no=?"); | |
$stmt_count->bindParam(1,$_POST["related"],SQLITE3_TEXT); | |
$relcat=$stmt_count->execute()->fetchArray(SQLITE3_NUM); | |
if(!$relcat) | |
return "Related post does not exist."; | |
else if($relcat[0]=="reply") | |
return "Nested replies are banned."; | |
} | |
$cat=$_POST["related"]?"reply":"comment"; | |
$byAdmin=$isAdmin?1:NULL; | |
if($byAdmin) | |
$info["by_admin"]=true; | |
//bind param as follows | |
$stmt->bindParam(1,$cat,SQLITE3_TEXT); | |
$stmt->bindParam(2,$_POST["name"],SQLITE3_TEXT); | |
$stmt->bindParam(3,$_POST["email"],SQLITE3_TEXT); | |
$stmt->bindParam(4,$_POST["comment"],SQLITE3_TEXT); | |
$stmt->bindParam(5,$_POST["related"],SQLITE3_TEXT); | |
$stmt->bindParam(6,$byAdmin,SQLITE3_INTEGER); | |
//id and timestamp will automatically be added, | |
// so we don't need to worry about them. | |
$stmt->execute(); | |
return false; | |
} | |
$et=microtime(true); | |
//array works like dict in python | |
$rtn=array(); | |
$info=array(); | |
$data=array(); | |
if($action=="write"){ | |
$result=writeData(); | |
if(!$result){ | |
$rtn["status"]="ok"; | |
$rtn["msg"]="Data is successfully saved."; | |
}else{ | |
$rtn["status"]="error"; | |
$rtn["msg"]=$result; | |
} | |
}else if($action=="read"){ | |
$info["status"]="ok"; | |
$result=$db->query("select `no`,`name`, `flagged`, `email`, `comment`, `by_admin`, datetime(`timestamp`,'+8 hours') as `timestamp` from book order by `no` desc"); | |
while($arr=$result->fetchArray(SQLITE3_ASSOC)){ | |
$arr["comment"]=normalizeNL($arr["comment"]); | |
$data[]=$arr["flagged"]?makeFlaggedMessage($arr):$arr; | |
//must ensure that the related data does exist!!!! | |
} | |
}else if($action=="hide"){ | |
if(!$isAdmin){ | |
$rtn["status"]="error"; | |
$rtn["msg"]="Auth failed. This can only be done by administrators."; | |
}else{ | |
$stmt=$db->prepare("update book set `flagged`= (`flagged` is null or(not `flagged`)) where no=?"); | |
if(isset($_POST["comment"])){ | |
$stmt->bindParam(1,$_POST["comment"],SQLITE3_TEXT); | |
$stmt->execute(); | |
if($affect_rows=$db->changes()){ | |
$rtn["status"]="ok"; | |
$info["affect_rows"]=$affect_rows; | |
}else{ | |
$rtn["status"]="error"; | |
$rtn["msg"]="No record found."; | |
} | |
}else{ | |
$rtn["status"]="error"; | |
$rtn["msg"]="Invalid parameters."; | |
} | |
} | |
}else{ | |
//not supported action | |
$rtn["status"]="error"; | |
$rtn["msg"]="Specified action is not supported!"; | |
} | |
$info["elapsed-time"]=round((microtime(true)-$et)*1000,3); | |
$rtn["info"]=$info; | |
$rtn["data"]=$data; | |
print json_encode($rtn); | |
//Do not leave anything beyond the end of the tag! | |
?> |