Продолжение запила API

Создание постов, новые настройки в конфиге
This commit is contained in:
Shr3dd3r 2024-01-20 00:02:51 +03:00
parent c48f837738
commit e180c04e44
3 changed files with 103 additions and 27 deletions

View File

@ -22,6 +22,44 @@ if ($IS_FRONTEND) {
// Functions
/*
* FUNCTION
* Parse tags from raw string
*/
function Post_ParseRawTagString (string $str): ReturnT {
global $Config;
$allowedSymbols = $Config["posting"]["tags"]["allowed_syms"];
$maxTagLength = $Config["posting"]["tags"]["max_single_length"];
$strLength = strlen($str);
$currLen = 0;
$currTag = "";
$result = array();
for ($i = 0; $i < $strLength; ++$i) {
if ($str[$i] === ",") {
if ($currLen) {
$result[] = $currTag;
$currLen = 0;
} else {
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "syntax error while trying to parse tags");
}
} elseif ($str[$i] !== " " && $str[$i] !== "\t") {
$currTag .= $str[$i];
if (++$currLen > $maxTagLength)
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "tag too large: $currTag");
}
}
$preg_str = "/[^" . $allowedSymbols . "]/";
foreach ($result as $tag) {
if (preg_match($preg_str, $tag))
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "only allowed symbols in tags are: " . $allowedSymbols);
}
return new ReturnT(data: $result);
}
/*
* FUNCTION
* Check if image size properties are valid
@ -38,7 +76,7 @@ function Post_ImgResIsValid ($x, $y): bool {
* FUNCTION
* Create preview version of image
*/
function Post_CreatePreviewFromImage ($src, $dst): ReturnT {
function Post_CreatePreviewFromImage (string $src, string $dst): ReturnT {
$img = null;
// Reading image from source path
@ -56,34 +94,45 @@ function Post_CreatePreviewFromImage ($src, $dst): ReturnT {
// Saving it as LQ JPEG
imagejpeg($img, $dst, 30);
if (!file_exists($dst)) // $src isnt our responsibility, $dst is
return new ReturnT(err_code: E_UNS_UNEXPECTED, err_desc: "failed to create preview");
return new ReturnT(data: true);
}
/*
* FUNCTION
* Store image
* Stores image and returns paths to picture and its preview
*/
function Post_StoreImage ($path, $preview = true): ReturnT {
function Post_StoreImage (string $path): ReturnT {
global $Config;
// Paths
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$fileName = strval(time()) . "_" . GenerateRandomString(4);
$targetDir = "../../" . $Config["media"]["pics_path"];
$targetPath = JoinPaths($targetDir, $fileName . "." . $ext);
$targetPath = Utils_JoinPaths($targetDir, $fileName . "." . $ext);
// Creating preview file
if ($Config["media"]["previews_enabled"] && $preview) {
if ($Config["media"]["previews_enabled"]) {
$previewDir = "../../" . $Config["media"]["prevs_path"];
$previewPath = JoinPaths($previewDir, $fileName . ".jpg");
$previewPath = Utils_JoinPaths($previewDir, $fileName . ".jpg");
$res = Post_CreatePreviewFromImage($path, $previewPath);
if ($res.IsError())
if ($res->IsError()) // $path isnt our responsibility
return $res;
}
move_uploaded_file($path, $targetPath);
return new ReturnT(data: true);
if (!file_exists($targetPath)) { // however, $previewPath IS our responsibility
unlink($previewPath);
return new ReturnT(err_code: E_UNS_UNEXPECTED, err_desc: "failed to move uploaded file");
}
return new ReturnT(data: array(
"preview" => $previewPath,
"picture" => $targetPath
));
}
/*
@ -103,7 +152,7 @@ function Post_Create (
$result = null;
// Author ID should exist
// Author ID must exist
if (!User_IDExist($author_id))
return new ReturnT(err_code: E_UIN_WRONGID, err_desc: "specified user id does not exist");
@ -114,6 +163,8 @@ function Post_Create (
if ($s->execute() === false)
return new ReturnT(err_code: E_DBE_INSERTFAIL, err_desc: "failed to create post record in DB");
$result = true;
return new ReturnT(data: $result);
}
@ -145,9 +196,23 @@ function Post_Create_Method (array $req, array $files): ReturnT {
if (!(isset($req["tags"]) && isset($files["pic"])))
return new ReturnT(err_code: E_UIN_INSUFARGS, err_desc: "tags and picture are necessary");
// TODO: add rate-limiting, instead of this
// Check user role
if (User_HasRole($THIS_USER, "newbie").GetData())
// Check tags
// If raw string length not fits into limit
$tagsLen = strlen($req["tags"]);
if ($tagsLen > $Config["posting"]["tags"]["max_raw_input_str_length"])
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "tags string length exceeds limit: " . strval($Config["posting"]["tags"]["max_raw_input_str_length"]));
elseif ($tagsLen < 1)
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "tags cant be empty");
// TODO: check if it is ASCII string
// Parsing tags
$parsedTags = Post_ParseRawTagString($req["tags"]);
if ($parsedTags->IsError())
return $parsedTags;
// TODO: check if tags are approved
$tags = implode(",", $parsedTags);
// Check user role TODO: add rate-limiting, instead of this
if (User_HasRole($THIS_USER, "newbie")->GetData())
return new ReturnT(err_code: E_ACS_INSUFROLE, err_desc: "newbies cant create posts");
// Check image properties
@ -167,15 +232,17 @@ function Post_Create_Method (array $req, array $files): ReturnT {
if (!Post_ImgResIsValid($SzX, $SzY))
return new ReturnT(err_code: E_UIN_IMGBADRES, err_desc: "image with that resolution or aspect ratio cant be accepted");
// Copy picture to storage folder
$res = Post_StoreImage($TmpFilePath, $Config["media"]["previews_enabled"]);
if ($res.IsError())
return $res;
// TODO
// Actions
// Copy picture to storage folder
$res = Post_StoreImage($TmpFilePath);
if ($res->IsError()) { // $TmpFilePath seemingly isnt our responsibility, BUT, only we know how and what to cleanup
unlink($TmpFilePath);
return $res;
}
$pic_path = $res["picture"];
$prev_path = $res["preview"];
return Post_Create($author_id, $tags, $pic_path, $title, $prev_path, $comms_enabled, false);
}
@ -184,7 +251,7 @@ function Post_Create_Method (array $req, array $files): ReturnT {
if (Utils_ThisFileIsRequested(__FILE__)) {
require_once("../_json.php");
// TODO: cleanup if bad result
// TODO
}
?>

View File

@ -35,5 +35,14 @@
"image/jpeg",
"image/png"
]
},
"posting": {
"tags": {
"max_per_post": 256,
"max_single_length": 256,
"max_raw_input_str_length": 1536,
"allowed_syms": "a-zA-Z0-9_"
},
"max_title_length": 4096
}
}

View File

@ -3,20 +3,20 @@
// Notices stack
$NTFY_NoticesStack = array();
// Notices queue
$NTFY_NoticesQueue = array();
// Add new notice with selected type
function NTFY_AddNotice (string $text, string $type = "fail") {
global $NTFY_NoticesStack;
global $NTFY_NoticesQueue;
switch ($type) {
case "fail":
$NTFY_NoticesStack[] = "<div class=\"notification_fail\"><p>$text</p></div>";
$NTFY_NoticesQueue[] = "<div class=\"notification_fail\"><p>$text</p></div>";
break;
case "success":
$NTFY_NoticesStack[] = "<div class=\"notification_success\"><p>$text</p></div>";
$NTFY_NoticesQueue[] = "<div class=\"notification_success\"><p>$text</p></div>";
break;
default:
die("invalid notification type: $type");
@ -25,8 +25,8 @@ function NTFY_AddNotice (string $text, string $type = "fail") {
// Echo all notifications
function NTFY_EchoAllNotices () {
global $NTFY_NoticesStack;
foreach ($NTFY_NoticesStack as $notice) {
global $NTFY_NoticesQueue;
foreach ($NTFY_NoticesQueue as $notice) {
echo "$notice\n";
}
}